An Introduction to MEFedMVVM - Part 1
Join the DZone community and get the full member experience.
Join For Freeintro
this is a small introduction to mefedmvvm , a library that i built with the help of some fellow wpf disciples, peter o’hanlon and glenn block (aka mr.mef) . this library will enable you to quickly create viewmodels that consume services and inject these viewmodels in your view’s datacontext. it will also enable you to work better with your fellow friend, “the designer” by leveraging design time data and many other ui friendly stuff. with this library you can create wpf/silverlight applications seamlessly since the api is common for both wpf and silverlight .
goals
- write code that works for sl and wpf.
- enable design time data.
- enable loosely coupled bridge between view and viewmodel.
- enable easy viewmodel discovery and injection mechanism.
- make composition super easy by leveraging mef capabilities (without coupling your code with mef).
how do i use this thing?
ok so these are the first 3 basic steps .
1. add a reference to mefedmvvm.wpf/mefedmvvm.sl (you also have to add a reference to dlls that are located in the dependencies folder of the source code if you are not including the library source code in your solution.)
2. add an attribute somewhere in your project to mark the assembly as a “mefedmvvm” assembly, [assembly: designtimecatalogattribute]. this is used so that mefedmvvm only looks for exported items in the marked assemblies. this makes initialization faster.
now begins the mefedmvvm fun….
3. make your viewmodel discoverable by decorating it with [exportviewmodel(“mymefedviewmodel”)] and instruct the view to go find that viewmodel by setting an attached property meffed:viewmodellocator.viewmodel=”mymefedviewmodel”
so the view looks like this
<usercontrol x:class="mefedmvvmdemo.views.usersscreen"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:meffed="http:\\www.codeplex.com\mefedmvvm"
meffed:viewmodellocator.viewmodel="mymefedviewmodel">
and the viewmodel like this
[exportviewmodel("mymefedviewmodel")]
public class testviewmodel { }
and viola that is it…. you run the project and magically the viewmodel gets injected in the view…
i must say, i cannot take the credit for this magic, it’s all powered by the mighty mef!
ok so we injected the viewmodel in the view, but where the hell is the design time data???
well should i tell you or should i go to sleep ? mmmm…. thinking…
still thinking… aa well might as well tell you now that i started right
when creating viewmodels usually the data is coming from some service which is injected to the vm via dependency injection. what mefedmvvm will do for you is let you expose services and include meta data that gives extra information to the service. mefedmvvm uses this meta data to decide which service to give to the vm at runtime and which service to inject at design time.
this is how you expose services (for runtime)
[exportservice(servicetype.runtime, typeof(iusersservice))]
public class usersservice : iusersservice
this is how you expose services (for design time)
[exportservice(servicetype.designtime, typeof(iusersservice))]
public class designtimeusersservice : iusersservice
p.s you can also specify servicetype.both if you want the same service to be injected at runtime and design time.
once you make your services discoverable it’s time to start using them in your viewmodel. in order to do this, you must have your vm implement the iserviceconsumer interface, or if you are lazy like me just inherit from baseviewmodel. you also need to specify which services you want injected by specifying the different types in the exportviewmodel attribute. something like this
[exportviewmodel("vm1", typeof(iusersservice), typeof(ivisualstatemanager), typeof(idispatcherservice))]
public class testviewmodel : baseviewmodel
in the above code i am importing the iuserservice, the ivisualstatemanager and the idispatcher service into my view model. these services are injected when mefedmvvm creates an instance of the viewmodel into a servicelocator so you can get them by calling getservice<t>() from the onservicesinjected method. the code for this looks something like this
protected override void onservicesinjectedoverride()
{
var usersservice = getservice<iusersservice>();
var dispatcherservice = getservice<idispatcherservice>();
}
you might ask yourself why can’t i just import the services by using a standard [import] like in normal mef. basically when the mefedmvvm is looking for the correct services it is also doing some extra stuff that i will talk about in following blog posts (but i know you are curious so i’ll give you a hint…. ivisualstatemanager for example gets injected with the uielement that is requesting the viewmodel so that then the viewmodel can execute state without coupling to the vsm)
what comes out of the box?
out of the box this library supplies a number of things… here is a list of most of the stuff
common services
- imediator (use this to communicate from one viewmodel to another.
- iviewstatemanager (user this to invoke visualstates from the viewmodel)
- icontainerstatus (provides a loaded event and unloaded event, these are hooked to the loaded and unloaded events of the uielement that is consuming the viewmodel)
- idispatcher (provides a way so that you can call begininvoke on the dispatcher in a loosely coupled way so that you can mock this when doing unit tests)
- and many many many more to come….
- and many more you can create yourself.
basically this library is still learning how to walk, its still a
cute little baby… but the basics are in (so yea its a healthy cute
baby)… i will talk more on how you can create your own services that
bridge the viewmodel and the view in my next post (yet yea i know, i
know, you are curious… implement icontextaware in your service and you
get injected with the view that requested the viewmodel and then you can
do what the hell you want
. but don’t tell anyone i told you
)
other stuff
delegatecommand<t> (used to create commands without having to create a separate class that implements icommand)
baseviewmodel (implement inotifypropertychanged and you can raise propertychanged notifications in a strongly typed manner i.e onpropertychanged(() => users); . baseviewmodel also has some other benifits that i will discuss in my next post)
more stuff coming up … don’t don’t worry … we just built the basics
here
conclusion
why do i think this library has a lot of potential? well right now there are some things missing but the basics are there and it is really easy to add new stuff now that we have a solid base. there are loads of things that i did not mention in this post since i wanted this post to be just a mini introduction. i will have part 2,3 n of this post coming up shortly where i will go into more dept of the library and how you can extend it and bend it to your will.
i suggest you download the code from codeplex and start playing with it. right now i really need your help and get as much feedback / bug reports as possible … warning: right now i am doing loads of changes to the code so please do not use this in production projects.
i hope you like this new library… just a word of caution when using
this library…. it can get really addictive
myself am suffering this side effect right
now … hehe
download source and mef it up! http://mefedmvvm.codeplex.com/
Published at DZone with permission of Marlon Grech. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
File Upload Security and Malware Protection
-
Top 10 Pillars of Zero Trust Networks
-
Merge GraphQL Schemas Using Apollo Server and Koa
-
Exploratory Testing Tutorial: A Comprehensive Guide With Examples and Best Practices
Comments