Closures in C# can be evil

I had a problem with yield and closures. A friend Glenn Block gave me a good link on this. you can read it here >> http://codebetter.com/blogs/matthew.podwysocki/archive/2008/09/12/side-effects-and-functional-programming.aspx

here is an abstract from the blog about the problem. This can cause a lot of pain and that is why I am sharing it so that you do not fall in the same trap!

Closures and Lazy Evaluation

One last topic for this post revolves around variable instantiation around closures and what it means to you in regards to lazy evaluation.  Let’s look at a quick example of some of the issues you might face. 

C#

var contents = new List<Func<int>>();
var s = new StringBuilder();
for (var i = 4; i < 7; i++)
    contents.Add(() => i);
for (var k = 0; k < contents.Count; k++)
    s.Append(contents[k]());
Console.WriteLine(s);

What we might expect the results to be in this case would be 456.  But that’s not the case at all here.  In fact, the answer you will get is 777.  Why is that?  Well, it has to do with the way that the C# compiler creates a helper class to enable this closure.  If you’re like me and have Resharper, you’ll notice that it gives a warning about this with "Access to modified closure".  If we change this to give ourselves a local variable inside the loop closure construct to initialize the value properly.  If we do that and change our code, it will now look like this:

C#

var contents = new List<Func<int>>();
var s = new StringBuilder();
for (var i = 4; i < 7; i++)
{
var j = i;
    contents.Add(() => j);
}
for (var k = 0; k < contents.Count; k++)
    s.Append(contents[k]());
Console.WriteLine(s);

Jason Olson has a pretty good explanation in his post "Lambdas – Know Your Closures".

 

Hope it helps!

INotifyPropertyChanged… I am fed up of handling events just to know when a property changed

The INotifyPropertyChanged is what tells the WPF/SL binding that a property changed and that the binding should be updated. For this purpose its quite good. But what many times we end up doing is; handling the PropertyChanged in code so that we get notified that a property changed. An example is a ViewModel that need to know when a property in the underlying model changed and if it did it will do something to facilitate the View.

Doing this in code is a bit ugly because you base everything on “magic strings”.. something like this

image

Another problem is that if you use an anonymous delegate you need to do loads of tricks in order to unregister to the event.

In order to over come this I created a PropertyObserver that handles these 2 issues. (Please note that there are already others, Philip Sumi has a good one here and  Josh Smith has a good one here. I created my own since I wanted to have extra + different way of doing it). Also this problem can be solved easily using Rx, I am doing this sample so that you do not need to depend on Rx.

The implementation I did is very simple, I created a PropertyObserver class that uses lambdas so that you tell it what property you want to subscribe to and pass an action to do your “Property Changed handling”. What I also did is an attached method so that all objects that implement INotifyPropertyChanged can simple handle the property changed… so the code looks like this

image

One would ask and how do I unregister? is this using weak event pattern? The answer is NO. I wanted to keep it simple and cross platform (for WPF and SL). what you can do is a more Rx approach… basically in RX if you subscibe to something you get an IDisposable in return so that you can Dispose (i.e in our case unsubscribe) when you want like this

image

as you can see here I am wrapping the call in a using statement… but if you need to unsubscribe in any specific state you can store the IDisposable that you get from the Do call and call Dispose to unsubscribe.

Many times you need this for only one time i.e a property changes you do something and you do not want to get called any more times. For this I created a DoOnce. This will unsubscribe for you once the property changes once. The API is very similar and looks like this

image

That’s more or less it.

Big thanks go to Diego Colombo and John Rayner (two champs that work with me) for the help and input they gave me on this 🙂 You rock guys!

You can download the code here.

OR if you have MEFedMVVM download the latest version since its in MEFedMVVM.

MEFedMVVM: Testability

>> If you are new to MEFedMVVM, I suggest you first read this article to get started: https://marlongrech.wordpress.com/2010/05/23/mefedmvvm-v1-0-explained/

Having solid unit tests is key to have successful projects. When these projects get really large and especially if there are several developers on the project. Once you get used to unit testing you feel un-complete if you do not unit test your code. One of the virtues of the Art of Unit testing is Mocking. Mocking is really important while you are unit testing so you remove all the dependencies of the code you are testing and you just test what you really want to test.

“Testability” is something that I take very seriously and in MEFedMVVM it was no exception.

Unit testing best friend is Dependency Injection(since with this you can mock all the dependencies); MEFedMVVM leverages MEF thus this comes for free. Having said that what is also really cool with MEFedMVVM is that all services exposed can be mocked. By services I do not just mean backend services (example a service that connects to a DB to load data) but also UI services (or as I usually refer to them MEFedMVVM IContextAware services).

Here is a sample unit test (you can see this in the source code of MEFedMVVM) Please note I am using Rhino Mocks as my mocking framework for this sample.

 

image

As you can see in this test I am testing that when I set the SelectedUser property on the ViewModel (which would be updated by binding at runtime) I send a mediator message. I can do this because the Mediator that comes out of the box with MEFedMVVM is exposed as an IMediator thus I can easily mock it and test that I am doing the right calls to the Mediator.

What is really cool is that I can even mock behaviours like ViewModel setting a Visual State or even testing that on Loaded event of the View the ViewModel does something (in my case it will load some data from a service)

image

As you can see in the above code, I am testing that when the ContainerLoaded event (which is an event in the MEFedMVVM IContainerStatus an IContextAware service that abstracts the Loaded and unloaded event of the View) of the IContainerStatus is raised, I am setting the “Welcome” state via the IVisualStateManager ( which is another MEFedMVVM IContextAware service that lets you set a specific VisualState on the View).

I am also testing that the first user is selected by default and that my data is loaded.

Conclusion

I think the fact that I can mock any dependency that my ViewModel has (even if it is a “UI” thing) is a really powerful thing! Currently MEFedMVVM is helping me and my team a lot and we are finding that Unit Testing with MEFedMVVM is really awesome. Having said that if you have any comments/suggestion on how to make testing easier with this library, Please do let me know.

Thanks

Download MEFedMVVM

http://mefedmvvm.codeplex.com/

MEFedMVVM v1.0 Explained

Introduction

In this post I will cover the basic things you need to know for quickly start building MEFedMVVM powered WPF and Silverlight. For those new to MEFedMVVM here is a quicky on what MEFedMVVM is all about.

MEF is an awesome framework for introducing extensibility in your projects. MEF is built in a generic manner so that you can use it in many different scenarios, example Backend service, ASP.NET application and yes also WPF and Silverlight. Because of MEF being so generic there is no out of the box support for MVVM (example ViewModelLocator so that a View can request a ViewModel to get injected in DataContext, etc…). One of the goals of MEFedMVVM  is to do all the MEF plumbing for you so that you can simple say “I want to Export this ViewModel” and then you can have a View that says “I would like that specific ViewModel” and BANG, MEFedMVVM will do all the plumbing by leveraging the Mighty MEF. Besides this MEFedMVVM has DesignTime Data capabilities. MEFedMVVM is very much Blend Aware so that you can add design time stuff (you’ll read more about this in a later section).

>> Are there any special requirements to use MEFedMVVM?

Yes and no 🙂 All the testing I did was with .NET 4.0 for WPF and Silverlight 4. Having said that there are users of MEFedMVVM using .NET 3.5. Till now no one reported any major bugs but be warned that myself I only tested MEFedMVVM with .NET 4.0 for WPF and Silverlight 4. With regards to MEFedMVVM at design time; only Blend 4 RC or newer are supported by MEFedMVVM, so unless you have Blend 4 RC or newer there is a chance that MEFedMVVM does not work as one would expect (especially with Blend 4 Beta).

>> How stable is the current code?

It’s pretty much stable. I am really pleased to announce that I marked change set 48734 as stable on Codeplex. Myself and some other guys at work are using it already in production projects and till now we did not find any issues. Having said that if you encounter any issue please contact me and I will do the best I can to help out.

>> I am already using an MVVM Framework! Can I use MEFedMVVM side by side?

Do not worry! If you are using an MVVM Framework go on using it, MEFedMVVM can work side by side. I am currently working with some MVVM library authors to provide samples of how to use MEFedMVVM with other MVVM libraries. On the other hand if you want to use MEfedMVVM on its own, well MEFedMVVM  will give you some basic things out of the box as well such as DelegateCommand<T>, Mediator, NotifyPropertyChangedBase and Visual State Management.

How can I start?

Let’s start by having a look at some core things in MEFedMVVM that you will be using to expose ViewModels for View to consume.

So first of all you have to add a reference to MEFedMVVM.WPF/MEFedMVVM.SL depending on if you are in SL or WPF (Api is 100% the same for both platforms!). You also need to add a reference to System.ComponentModel.Composition otherwise VS will not let you use the ExportViewModel or ExportService attribute.

Lesson 1: How to expose a ViewModel so that a View knows how to consume it?

MEFedMVVM: ExportViewModel

 

 

 

 

In order to expose a ViewModel all you have to do is decorate your VM with the ExportViewModel attribute and give the ViewModel a name so that the View can request that ViewModel by using the name you assigned to the ViewModel.

You might be wondering at this point, but how does that work? Well easy, MEFedMVVM is using MEF to get an Import from the Contract name (the name you gave the ViewModel) ignoring the type since a ViewModel can be of any type in MEFedMVVM (this was done like so so that you can have MEFedMVVM working side by side with any other MVVM library. MEFedMVVM does not dictate that your ViewModel has to inherit from any base class). A viewmodel import in MEF terms would look like this [Import(“ViewModelName”]public object ViewModel {get; set; }. Of course this is not how MEFedMVVM is doing it, in order for this to work MEFedMVVM had to quite a bit of plumbing to get this right 🙂

[Advanced] Besides a normal export of a ViewModel can also do a DataContextAware export. This is an advanced feature and there are only few use cases for it. To know know more on what this is read the DataContextAware section in this article.

 

 

Lesson 2: How can a View consume a ViewModel?

image

 

 

In order to make a View consume a ViewModel that you exposed via the ExportViewModel you have to specify it in the attached property ViewModelLocator.ViewModel.

By specifying this property MEFedMVVM will go looking for the ViewModel that has the name you specifying in the attached property.

[Advanced]In case MEFedMVVM does not find the ViewModel you requested it will store a weak reference of the View and the contract name it was requesting so that if a MEF recomposition happens it can satisfy that import and inject the ViewModel. This is a handy feature if you are build Silverlight applications that use Partitioning and downloads parts of the application async.

Where are we?

Well that’s it. With those 2 steps you are pretty much done! Expose a ViewModel and have a View consume it. But for more complex scenarios you need more then that!

Here are some of the main MEFedMVVM features and briefly how to use them… This will enable more complex scenarios, if you just want a ViewModel injected in a View you can stop here.

>> Dependency Injection for Runtime, Design Time and why not have Both if you are lazy 🙂

In a classical MVVM the usual approach is that the ViewModel does logic to facilitate the View. BUT a ViewModel does not do stuff like connecting to a database and get records from the database! That is the responsibility of a backend service which would then be consumed by the ViewModel (via Dependency Injection so that we can mock the service while testing) to get the data and expose it to View. With MEFedMVVM you can have dependency injection of services via standard MEF Imports.
So you can do like this (by using [ImportingConstructor])

image  OR like this

image

As you can see this is standard MEF exports, nothing to it… what is cool is that you do not have to worry about asking the CompositionContainer (or maybe in SL your CompositionInitializer) to satisfy your imports and clutter the code of your ViewModel. MEFedMVVM will do it for you!

The exports can be done via standard MEF exports (i.e [Export]public class MyService { } ), BUT MEFedMVVM has an export attribute of its own specifically for services so that you can control if the Service is injected in Runtime only – DesignTime only or if you want for both (obviously if you want it for both you do not need to use the ExportService because the same behaviour can be achieved via a standard MEF Export, but its there just in case the Framework will start doing something smarter with it in future).

So a Design time service would look something like this ( in this implementation you would make the service return design time data)

image

and for runtime it would be like this (in this implementation you would have your service connecting to the DB/Web Service/ what have you )

image

>> IContextAware services

This is a very powerful technique to have services that are “ContextAware”. What does that mean? what do you mean by context aware? I get a lot of questions on this and I think in the next version of MEFedMVVM will change its name to IViewAware since the context in MEFedMVVM will be the View requesting the service.

The idea is that if your service implements the IContextAware interface of MEFedMVVM, MEFedMVVM will call the InjectContext passing the View that is requesting the ViewModel which requires the service. Confusing isn’t it 🙂 Here is a Diagram that explain what happens

image

 

 

So why is this so cool? Well with this in place you can do really cool stuff. How many times did you have to create an attached property in order to have you View some MVVM friendly thing? Well now instead of an attached property you can have a service and this service will get injected in the ViewModel thus the ViewModel has now much more control then a simple attached property.

A very good example of this is the IVisualStateManager that comes out of the box with MEFedMVVM. Basically with IVisualStateManager a ViewModel can invoke VisualStates on a View with in code without coupling the ViewModel and the View. You can even mock the IVisualStateManager while doing unit testing and do assertions if the ViewModel did not invoke the correct state at the correct time.

Out of the Box MEFedMVVM has 3 IContextAwareServices

>> IVisualStateManager – This is used to invoke VisualStates. This is definitely my favorite and probably the answer to “how do I do animations in MVVM and give full control to the Designer?”

>>IContainerStatus – This was more of an experiment but hey it is quite useful sometimes. Basically the IContainerStatus hooks to the Loaded and Unloaded events of the View and raises its own events. In this manner the ViewModel can do stuff on load of the View (example only load data when the Loaded event is raised and maybe dispose that data when unloaded).

>> IDispatcherService – This is an abstraction on the Dispatcher so that the ViewModel can invoke operation to happen strictly on the Dispatcher thread.

>> More to come 🙂

 

 

 

 

>> Mediator

As such the Mediator has nothing to do with MEF but when it comes MVVM I feel that Mediator is essential! I use it a lot because it is a way of communicating between entities without each entity knowing of the other. Just like an Event Aggregator. What is interesting is how I exposed this in MEFedMVVM. So for starters there is an interface IMediator so that you can mock it as you like. But what is really cool (and this is a MEF feature) is that a MEdiator would only work if the instance is shared. Now a standard MEF import would be creating a new instance of the object being requested by default, BUT if you decorate the Export with [PartCreationPolicy(System.ComponentModel.Composition.CreationPolicy.Shared)] MEF will do some magic and instead of creating a new instance for the service, it will staisfy the import using a shared instance of that class. Of course this technique can be used for any kind of export, so if you every have a service that need to be shared all you have to do is put the PartCreationPolicy on top of the Export to export the service.

DESIGN TIME >> When you say this will work in Blend what exactly do you mean by that?

Let’s say you have a property in your ViewModel and in the constructor of the VM you set this property to some string, let’s say “Hello World :)”. In your View you wire up the View to the ViewModel using MEFedMVVM and in your View, you create a TextBlock and bind to the ViewModel property. When you open up Blend (if not already in it, you will see the text “Hello World :)” rendered on the screen! and yea if you run the app you would also get the same behavior 🙂 Basically the idea is that MEFedMVVM will do a MEF composition for design time as well as at runtime. for design time MEFedMVVM does some clever things to build the composion so that it ensures that all your Views get satisfied with the ViewModels.

For Design Time, MEFedMVVM offers loads of features besides ViewModel injection. Here are some other goodies that come out of the box with MEFedMVVM.

>> Design Time Services (explained above)
If you you want to make sure that your Designer has full Design Time Data and maybe even behaviour you can do this via Design Time Services. In order to do this you have to design your ViewModel (usually all of us do it that way by default to support unit testing) to use Dependency Injection. Besides this you need to create a Service for Design time (just like you would mock a service for your ViewModel for Unit Testing) and expose that service by decorating it with the ExportService attribute and pass ServiceTypes.DesignTime. Your service would look something like this

 

[ExportService(ServiceType.DesignTime, typeof(IIngredientService))]
public class DesignTimeIngredientService : IIngredientService
{
……
}

This is an opt in feature of course but I recommend that you have a look at it and give it a try since it’s really awesome. Basically if it is working at design time it will work at runtime (unless you have a bug in the runtime service of course 🙂 )

>> IDesignTimeAware

image

This interface does some magic at design time and does nothing at runtime. Some times you have some property in the ViewModel (or maybe even some operation) that you need to execute on the ViewModel at Design time. With the IDesignTimeAware you can do exactly that. In order to leverage this feature your ViewModel must implement the IDesignTimeAware interface and this will include a DesignTimeInitialization method. In this method you can write your own code and MEFedMVVM will make sure to invoke that method when the ViewModel is initialized at design time. At runtime this method will be ignored by MEFedMVVM.

 

 

 

>> DataContextAware ViewModels

This is one of my favorite features I must say! The scenario for this feature is very specific. You would want to use this feature if >>

1. You have an implicit DataTemplate (ex: <DataTemplate DataType=”{x:Type my:ViewModelX}”> ) thus at runtime a ViewModel is injected by the WPF runtime but in Blend the designer is left without any design time data!
2.  You have a case of Parent Child ViewModel. Example: You have a ViewModel that has a list of child ViewModels and in the UI you bind to the list of ViewModel in an ItemsControl and have an ItemTemplate to tell WPF/SL how to render that ViewModel.

The above are the 2 case I created this feature for yet of course this can be used for other things if you like!

If we think about the 2 scenarios that I specified above you can immediately see why those scenarios can work at runtime but not at Design Time. The problem is that at design time the designer can be working on only a specific part of the UI (example the Child UI i.e the User Control that renders the ChildViewModel). In this case the ChildView would not have the attached property that asks for a ViewModel to be injected because we would not want to inject a ViewModel as at runtime that ViewModel would be coming from the ParentViewModel. In order to accomplish this the ExportViewModel has a parameter where you can tell it I want the ViewModel only to be injected at design time, BUT I would also like MEFedMVVM to satisfy my imports when at runtime. You specify this by doing so..

image  As you can see by passing true in the constructor for the ExportViewModel, you are setting the IsDataContextAware to true thus you will start leveraging this feature.

At design time this will work just like a normal ExportViewModel, so it will create an instance of the ViewModel and inject it in the View datacontext. But at runtime this will do something more clever. I will hook to the DataContextChanged event (in WPF, in SL this is not available thus it is hooked to the Loaded event. This might affect you depending on how you are setting the ViewModel to the View but it will work for most cases, specifically for the cases I specified above) and satisfy the imports of the ViewModel. The runtime behaviour is really helpful especially if you are using some of the core MEFedMVVM features such as IVisualStateManager.

Tips for Design Time Data

>> If some design time data does not show attach Visual Studio to Blend so you can debug and see what is going on.

>> Many times when you reference assemblies that have Exports you might end up having funny composition errors; If you do not have strongly names assemblies Blend will load multiple version of the same assembly and this usually result in issues at design time. I always try to sign my assemblies so that I do not get such issue at design time + its always a good practice to sign your assemblies anyway

Conclusion

I am now using MEFedMVVM in all my new projects and I am really enjoying it. It enables me to quickly start a project without having to worry, what should I use for Dependency Injection, How do I give Design Time Data to the ViewModel etc etc… Of course this is work in progress so you might stumble upon a bug or 2 🙂 but I am pretty much committed in investing more time on this framework so if you have suggestions or find bugs please do let me know.

I hope you like MEFedMVVM and that it can help you like it is helping me in everyday projects.

Download MEFedMVVM and Samples for usage from CodePlex

MEFedMVVM changes >> from cool to cooler

MEFedMVVM-Logo2After some discussions with Mr. MEF and a lot of MEF “disassembly and learn” sessions with Reflector, I finally managed to refactor MEFedMVVM and make it utilize more the power of MEF…
Besides this I had a change of Vision for MEFedMVVM. There are loads of awesome MVVM libraries out there, MEFedMVVM should not be competing with these and replicating what these libraries do but add on to them by providing ViewModel injections, Design Time vs Runtime services for Design Time Data, IDesignTimeAware ViewModels, IContextAware services and many other stuff …

I am working with the authors of 2 awesome MVVM libraries and soon we will see a Goldlight version using MEFedMVVM and also Cinch MEFedMVVM enabled 🙂 hopefully we will see more side by side usage of MEFedMVVM with other MVVM libraries.

We rebuilt how MEFedMVVM creates the MEF Composition Container …

Composition in MEFedMVVM

Why this huge code refactoring…

Before, MEFedMVVM relied on CompositionInitializer Satisfy imports which was importing all ViewModels and all Services in your solution… The side effect of this was CompositionInitializer relies on calling CompositionHost.Initialize which can only be called once (in Blend this is a bit hard since blend will re invoke static stuff when you rebuild the project). Besides that maybe you do not want to MIX the MEFedMVVM Composition with your own…

To satisfy an import of all the ViewModels and Services MEFedMVVM was relying on ExportFactory<object, IViewModelMetaData/IServiceMetaData>. As you can see this dictates that all ViewModels and Services where exported as type object… This is done implicitly for you from the ExportViewModelAttribute and ExportServiceAttribute. For ViewModels its ok to be exported as type object since you never rely need a ViewModel to be imported in another ViewModel, if you need this you should reconsider because ViewModels should not be coupled together (unless you have a child vm parent vm relation where you usually would create the Child VM from the Parent VM and pass the instance of the parent)*. But when it comes to services sometimes services need to be injected to other services not just to ViewModels… Now if you export the service as type object you cannot rely do a standard MEF import to get it…

*Having said that if you really really need a VM import do a standard Import and specify the ContractName as VMExport{YourViewModelContractName}. so yea you can still get it via a standard import 🙂

This problem is now solved by the MEFedMVVMCatalog. The export for services was done as type object so that MEFedMVVM could get all services and check if they are design time or runtime and depending on that inject the proper service in the ViewModel. Now MEFedMVVM catalog does this automatically because when an import is requested, depending on if its runtime or designtime MEFedMVVM will return the proper services. What is cool is that now you can import services using the standard MEF way.

 [ImportingConstructor]
public SelectedUserViewModel(IMyService service)
{ }

OR

[Import]
public IMyService MyService { get; set; }

Bye bye ServiceLocator and hello MEFness 🙂

As I said before now you can import a Service via standard MEF methods (i.e [Import] or [ImportingConstructor]). This means that your VM does not need to implement the IServiceConsumer anymore or inherit from BaseViewModel. If you are using a framework that already has a BaseViewModel you can continue using it 🙂 If you need a BaseViewModel that simply implements INotifyPropertyChanged MEFedMVVM has NotifyPropertyChangedBase but nothing more… I don’t see MEFedMVVM as a Framework to replace existing MVVM frameworks. MEFedMVVM is now a Framework that can work side by side with any existing MVVM framework that you like.

Being able to specify the imports for the services (and MEF injecting design time or runtime depending on when the VM is created) gives you more flexibility because you can specify things such as CreationPolicy etc. Besides this it means that now Services can be injected into other services etc etc…

So yea now an Export of ViewModel is simple [ExportViewModel(“MyVM”)] or if you need the VM to only be injected at DesignTime because the ViewModel is rendered from a DataTemplate thus the VM instance will already be injected user the DataContextAware VM feature i.e [ExportViewModel(“MyVM”, true)] . Passing true in the export does a bit of magic because it will not create an instance of the VM at runtime but it will still satisy any imports on that VM, at DesignTime it behaves normally i.e it creates the instance of the VM and injects it in the View. This is useful if the VM is being injected via some DataTemplate implicitly.

Bye bye DesignTimeCatalogAttribute for assemblies

Before MEFedMVVM was loading all assemblies that where marked with the DesignTime attribute when in Design Time. The problem with this was that if you forget to put this in your assembly MEFedMVVM would not load your assembly at design time.

The new MEFedMVVM does not require this because it looks at all assemblies checks you is using MEFedMVVM and if the assembly is using MEFedMVVM it loads it… This is done by looking at the reference assemblies of each assembly.

MEFedExportProvider for IContextAware services

THe question you might be asking is, How does MEFedMVVM inject the View to the Services that implement IContextAware?

The answer to this came from Mr. MEF. Create an Export Provider 🙂

MEFedMVVMExportProvider check if the export being injected implements IContextAware and if it does it sets the correct context (which is the View for IContextAware services). The view is given to the provider by the BasicViewModelInitializer/DataContextAwareViewModelInitializer.

StandardContextInjection

DataContextAwareContextInjection

Overriding the Runtime IComposer

The IComposer API changed… now you need to simple return the Catalog that you want MEFedMVVM to use to resolve the ViewModels and Services used by these ViewModels. I created 2 samples with Custom IComposers, 1 in Silverlight and 1 in WPF.

the API for IComposer now looks like this

  public interface IComposer
    {
        ComposablePartCatalog InitializeContainer();
    }

Conclusion

I hope you like the new MEFedMVVM… I am using this library on a large scale project and I am finding it really awesome. I did not make a release of the library yet so that I do a couple of large projects with this library and make sure that if I need to make API changes I can. Yet hopefully there will not be any more API changes since I think this big refactor made MEFedMVVM really light weight.

Let me know if you have any suggestions or if you hit any bugs. THANKS 🙂

Download MEFedMVVM from Codeplex: http://mefedmvvm.codeplex.com/

MEF DeploymentCatalog and Reference assemblies

In the Silverlight version of MEF one of the most powerful catalogs is the Deployment catalog. The Deployment catalog enables you to do some really cool stuff because you can download parts of the application when you need them.

I am using the Deployment Catalog on one of my projects and today I hit an issue that made me bang my head for over 30 minutes! The error was clear but it was a mystery why it was happening… 

The Error

I could see the error I was getting inside the event arguments of the DownloadCompleted event (e.Error) of the Deployment catalog. It was saying I had an import that could not be resolved since I had more then 1 export matching that requested import >> “More than one export was found that matches the constraint ”

The Import I had looked like this

[Import(AllowRecomposition=true)]
public ILogService Logger { get; set; }

But I had a single export like this

[Export(typeof(ILogService))]
public class Loger : ILogService

The Logger class was not in the assembly that I was trying to download it was in an assembly called CommonServices. I had a reference to the CommonServices assembly.

The main application that was using the Deployment Catalog to download the other assembly also had a reference to the CommonServices. Besides that it was also creating an Assembly Catalog for the CommonServices and put it in the aggregate Assembly that had the Deployment Catalog. I was doing this since the Main application was also using the ILogService as an import.

Why the Error?

After reading this post I immediately knew why the error was happening and how to solve it. Deployment Catalog will load all assemblies inside the XAP file thus all the assemblies that it references (The referenced assembly will be in the XAP file if you set Copy Local=true and by default VS does that for you). So in my case the Deployment Catalog was creating an Assembly Catalog for the CommonServices but I had already created that in my main application since I was importing ILogService in my main application.

The Solution

image The solution is easy set Copy Local to false for the referenced assemblies you do not want DeploymentCatalog to load at runtime. Your imports inside the assembly will still be staisfied since the Deployment Catalog is in the same Aggregate Catalog where you loaded the assembly as an AssemblyCatalog.

Hope this may help anyone having the same issue.

Enjoy your daily MEFing 🙂

How does MEFedMVVM compose the catalogs and how can I override the behavior? – MEFedMVVM Part 4

Some content may be out of date. See latest blog on changes made here.

Introduction

As you already know, MEFedMVVM is capable of composing the catalogs for you so that you do not have to worry about it both in Silverlight and in WPF. The composition happens a bit differently in SL and WPF so I will divide the “How to write a composer” section in 2, how it works for SL and how it works for WPF. But first let’s see what is common.

Please Note: This article is for advanced scenarios of using MEFedMVVM if you are using MEFedMVVM with its default behavior you do not need to do this since by default MEFedMVVM does the composition on its own. Yet if you want to have a silverlight app that uses multiple XAP files or a WPF app that is loading dlls that are not referenced by the main application and that reside somewhere else then the exe directory (or even Extensions folder of the base directory).

The LocatorBootstrapper and the IComposers

If you have been looking in the code of MEFedMVVM you’ll know that there is a class called LocatorBootstrapper. This class is responsible of checking if the MEF composition is done and if not I will ask the Composers to do so.

The “Composers” ? What the hell are these??

Basically these are instances of IComposer and there are 2 of these in the LocatorBootstrapper, one for DesignTime composition and one for Runtime. By default MEFedMVVM uses its own implementation of the IComposer which are DefaultRuntimeComposer and DefaultDesignTimeComposer but if you want to do something smarter (I will talk more on this later in the article) you can call the ApplyComposer method of the LocatorBootstrapper and inject a runtime composer that you implement. You must make sure to make this call before anything gets composed. A good place to do this is in the Application class constructor.

In the current version you cannot supply a DesignTime IComposer. I could have made the ApplyComposer API to accept another composer for DesignTime yet this method would be called always too late from Blend. I am currently working on a solution for this. Having said this, I do not see why you would want to override the default DesignTime composer since you still have control. I will talk more on this later in the post but any assembly marked with the DesignTimeCatalog will get picked up and loaded by the DefaultDesignTimeComposer. The only case where you would want to override this behavior is if you want to ignore the DesignTimeCatalog attribute. This is not suggested since not only it will slow down a lot the composition since blend loads many assemblies but it can also cause exceptions in Silverlight. I am open for suggestions so if you have any please let me know.

How can I create a Composer?

You do so by implementing the IComposer interface which looks like this.

   1: public interface IComposer

   2:     {

   3:         bool InitializeContainer();

   4:     }

In the InializeContainer you should put the code to initialize the Container and call CompositionHost.Initialize. (For WPF there is a catch that I will explain in the WPF section of the post).

Understanding and writing a Composer for Silverlight

What do the default MEFedMVVM composer do for SL?

The DesignTimeComposer will load all the assemblies that are decorated with the DesignTimeCatalog attribute in the AppDomain of Blend by using a trick explained here and create a CompositionContainer with MEF AssemblyCatalogs. So even if you have multiple XAP files MEFedMVVM will still get resolved as long as you put the DesignTimeCatalog attribute. If you forget to do this MEFedMVVM will put a message in the output window saying “No assemblies found for Design time. Quick tip… do not forget to put the DesignTimeCatalogAttribute for the assembly that contains your design time stuff. Even if its just a ViewModel you want to load.”. Yet in order to get this you need to have Blend attached with VisualStudio. (I am working hard on a solution to make this more obvious).

The Runtime Composer does not do anything. No really! It does not. The implementation simple returns true in the InitializeContainer method. This is because in SL CompositionInitializer.SatisfyImports (a class that is not present in WPF since WPF does not have System.ComponentModel.Composition.Initialization.dll) will create a container from the existing XAP.

So if you want to override the Runtime behavior for the SL version of MEFedMVVM you do not even have to call LocatorBootstrapper.ApplyComposer because for SL this is not doing anything anyway! But for the code to be the same for SL and WPF maybe its best if you do the call.

Quick Tip: If you are overriding the default container do not forget to add the an assembly catalog for the MEFedMVVM library, if you want to get injected with services that come out of the box with MEFedMVVM such as IVisualStateManager. Here is some sample code that is loading different XAP files

   1: AggregateCatalog aggregateCatalog = new AggregateCatalog();

   2: //add the catalogs for the current assembly and the MEFedMVVM assembly since we are overriding the default behavior

   3: aggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(ViewModelLocator).Assembly));

   4: aggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(App).Assembly));

   5: var listOfPluginXAPs = new[] { "Plugin1.xap" };

   6: foreach (var item in listOfPluginXAPs)

   7: {

   8:     DeploymentCatalog deploymentCatalog =

   9:       new DeploymentCatalog(item);

  10:  

  11:     aggregateCatalog.Catalogs.Add(deploymentCatalog);

  12:  

  13:     deploymentCatalog.DownloadCompleted += (s, args) =>

  14:     {

  15:         if (args.Error != null)

  16:             Debug.WriteLine("Error downloading plugin from " + item + " Exception: " + args.Error);

  17:         if (args.Cancelled)

  18:             Debug.WriteLine("Downloading of plugins was cancelled");

  19:  

  20:         PluginsDownloaded = true;

  21:     };

  22:  

  23:     deploymentCatalog.DownloadAsync();

  24: }

  25: CompositionHost.Initialize(aggregateCatalog);

Understanding and writing a Composer for WPF

What do the default MEFedMVVM composer do for WPF?

The DesignTimeComposer will load all the assemblies that are decorated with the DesignTimeCatalog attribute and create an AssemblyCatalog for each one. If you forget to put the DesignTimeCatalog attribute MEFedMVVM will put a message in the output window saying “No assemblies found for Design time. Quick tip… do not forget to put the DesignTimeCatalogAttribute for the assembly that contains your design time stuff. Even if its just a ViewModel you want to load.”. Yet in order to get this you need to have Blend attached with VisualStudio. (I am working hard on a solution to make this more obvious).

The RuntimeComposer will create a DirectoryCatalog for the AppDomain base directory and also checks if there is an Extensions folder and if so it will create a DirectoryCatalog for that folder as well. So yea if you have a set of plugins that are not being referenced by the main application, you do not even need to override the default behavior since you can make the plugins compile in an Extensions folder and MEFedMVVM will still load those assemblies. This is the code that creates the MEF catalog for the Default WPF Runtime Composer.

   1: var catalog = new AggregateCatalog();

   2: var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;

   3: var extensionPath = String.Format(@"{0}\Extensions\", baseDirectory);

   4: catalog.Catalogs.Add(new DirectoryCatalog(baseDirectory));

   5: catalog.Catalogs.Add(new DirectoryCatalog(baseDirectory, "*.exe"));

   6: if (Directory.Exists(extensionPath))

   7:     catalog.Catalogs.Add(new DirectoryCatalog(extensionPath));

   8: return catalog;

The “catch” with WPF version of MEFedMVVM

WPF does not have System.ComponentModel.Composition.Inialization so as such it does not have CompositionHost and CompositionInitializer but Mr.MEF, Glenn Block created this dll for us over here, and we are using it in MEFedMVVM, thus we benefit from the same code for SL and WPF. The only difference is that you have to do a trick when creating the CompositionContainer. You need to specify the ExportFactoryProvider when creating the CompositionContainer. like so

   1: var provider = new ExportFactoryProvider();

   2: var container = new CompositionContainer(catalog, provider);

   3: provider.SourceProvider = container;

   4: CompositionHost.Initialize(container);

If you fail to do so MEFedMVVM will not resolve the ViewModels and the Services since MEFedMVVM using ExportFactory to get the imports.

Enough talking (well as such its blogging 🙂 ) give us some code!

I did 2 samples one for Silverlight by using DeploymentCatalog to load assemblies from different xap files and one for WPF using DirectoryCatalog to load plugins from a folder called Plugins (this was just to show how you can do it because as such I could made the plugins compile in a Directory called Extensions and it would still have worked).

The source can be found in by download the code from http://mefedmvvm.codeplex.com/SourceControl/list/changesets there is a folder samples where you will find these 2 samples.

Conclusion

As you can see MEFedMVVM can also be used in more advanced scenarios where you want control over the MEF Composition of Catalogs. The default composition will work for most of the apps, yet for some (such as multiple XAP SL applications) you must have control over the composition.

As always feedback is much appreciated.

Download MEFedMVVM and start MEFing it up!

http://mefedmvvm.codeplex.com/

IContextAware services to bridge the gap between the View and the ViewModel – MEFedMVVM Part 3

Some content may be out of date. See latest blog on changes made here.

If you did not have look at MEFedMVVM introduction please so here. I also wrote an article on ExportViewModel here.

So what the hell is an IContextAwareService??

It is a service that knows about its context (which is the UIElement that invoked the import for the ViewModel and the services it depends on).

As I said in previous posts this is one of my favorite feature that MEFedMVVM has. Why well many times I created attached properties to extend UI functionality so that I can do proper MVVM. Yet some times it does not feel right because there is still a gap. The ViewModel does not have control over what the attached property does. Usually this is solved by exposing commands from the ViewModel and then you have another attached property that invokes the command which is magically databound ad what not. An example of something like this is VSM support I did a while ago here.

Enter MEFedMVVM with it’s IContextAwareServices.

You create this kind of service when you want to do some thing to or with the UI Element using the ViewModel as its DataContext. For example let’s say I want to know when the UIElement is Loaded and Unloaded so that my ViewModel does something smart only when you are Loading and Unloading. (please note this is just one example and I choose this example just to show the technique)

So let’s start by creating a service to do this.

First thing we have to do is create a class that Implements IContextAware. So our class will look like this

   1: public class DefaultContainerStatus : IContainerStatus


   2: {


   3:    #region IContextAware Members


   4:


   5:    public void InjectContext(object context)


   6:    {


   7:    }


   8: }

As you can see this interface has a method called InjectContext. This method will be called by MEFedMVVM with the UIElement that is requesting the ViewModel that has this service as Dependency. Since now we have the instance to the UIElement we can hook to the Loaded and Unloaded event and raise our own events that can later be mocked when unit testing the ViewModel.

So let’s create an interface to hide the default implementation of our service

   1: public interface IContainerStatus : IContextAware


   2: {


   3:     event Action ContainerLoaded;


   4:     event Action ContainerUnloaded;


   5: }

and now make the service implement that interface

   1: [ExportService(ServiceType.Both, typeof(IContainerStatus))]


   2: public class DefaultContainerStatus : IContainerStatus


   3: {


   4:     #region IContainerStatus Members


   5:


   6:     public event Action ContainerLoaded;


   7:


   8:     public event Action ContainerUnloaded;


   9:


  10:     #endregion


  11:


  12:     #region IContextAware Members


  13:


  14:     public void InjectContext(object context)


  15:     {


  16:         var element = context as FrameworkElement;


  17:         if (element != null)


  18:         {


  19:             element.Loaded += new RoutedEventHandler(ElementLoaded);


  20:             element.Unloaded += new RoutedEventHandler(ElementUnloaded);


  21:         }


  22:     }


  23:


  24:     void ElementLoaded(object sender, RoutedEventArgs e)


  25:     {


  26:         if (ContainerLoaded != null)


  27:             ContainerLoaded();


  28:     }


  29:


  30:     void ElementUnloaded(object sender, RoutedEventArgs e)


  31:     {


  32:         if (ContainerUnloaded != null)


  33:             ContainerUnloaded();


  34:     }


  35:


  36:     #endregion


  37: }

As you can see here all I am doing is handle the Loading and Unloading of the UIElement and raise the IContainerStatus events. In the code about I am also Exporting the service by using the ExportService attribute which tells MEFedMVVM that this is a service that can be consumed by ViewModels.

And that’s it folks. We are done. Now a ViewModel can start using this service by simple requesting it from the ExportViewModel attribute like so

   1: [ExportViewModel("VM1", typeof(IContainerStatus)]


   2: public class TestViewModel : BaseViewModel

One thing you should not forget is putting the [assembly: DesignTimeCatalog] somewhere in your project, otherwise MEFedMVVM will ignore your project. This is something that is not used at runtime but for design time it is crutial so that MEFedMVVM only loads your projects. MEFedMVVM will ignore any assembly at design time that does not have this attribute set!

Conclusion

There is a lot of potential in this approach. Currently MEFedMVVM exposes some out of the box IContextAware services which are

IViewStateManager – You can use this to invoke Visual States from your ViewModel.

IDispatcher – You can use this service to invoke delegates on the UI thread

IContainerStatus – You can use this service to get loaded and unloaded events.

and many more are coming up. But hey build your own if MEFedMVVM does not give you one already, it’s easy 🙂 and yea we would love to see what you come up with, if you want to contribute we are always happy to have your code 🙂

As always feedback is most appreciated.

Go MEF it up now 🙂 http://mefedmvvm.codeplex.com/

Leveraging MEFedMVVM ExportViewModel – MEFedMVVM Part 2

Some content may be out of date. See latest blog on changes made here.

In this post I will explain and show case what you can do with your VieModel by leveraging MEFedMVVM. If you want an introduction to MEFedMVVM please go here.

In order to make your ViewModel discoverable you simple decorate the ViewModel with ExportViewModel and give your view model a name so that the View can import the ViewModel by name. Some thing like this

ViewModel

   1: [ExportViewModel("VM1")]

   2: public class MyViewModel

and the view can look for this view model like this

   1: <UserControl x:Class="MEFedMVVMDemo.Views.UsersScreen"

   2:              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   3:              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   4:              xmlns:meffed="http:\\www.codeplex.com\MEFedMVVM"

   5:              meffed:ViewModelLocator.ViewModel="VM1">

The ViewModelLocator.ViewModel will leverage MEF to go get the exported ViewModel and set an instance of that ViewModel as the UserControl’s DataContext. BUT there is more stuff you can do.

 

DesignTime Data

The best way how to have design time data is by having Data Services injected in the ViewModel so that at design time you inject design time services and at runtime you inject the real services. This also allows you to better unit test because you can mock the data services while unit testing.

MEFedMVVM allows you to easily export services so that you can then import these services in the ViewModel. When you are exporting the service you also supply MetaData which is used by MEFedMVVM to decide which service to inject. Let’s do a quick example. Let’s say your ViewModel is using a service that implements IUserService to get a list of user from a database at runtime and you create another implementation of this service for design time that just returns a static list of Users. you would export these services like this

Design time Service

   1: [ExportService(ServiceType.DesignTime, typeof(IUsersService))]

   2: public class DesignTimeUsersService : IUsersService

   3: {

   4:    #region IUsersService Members

   5:  

   6:    public IList<Models.User> GetAllUsers(){}

   7: }

Runtime Service

   1: [ExportService(ServiceType.Runtime, typeof(IUsersService))]

   2: public class UsersService : IUsersService

   3: {

   4:    #region IUsersService Members

   5:  

   6:    public IList<Models.User> GetAllUsers()

   7: }

As you can see all you do is decorate the service with the Export Service attribute and specify if its Runtime or DesignTime. You can also specify ServiceType.Both if you want that service to be injected both at runtime and design time. I will talk more on the Export Service and what you can do with it in my next post. Just to give you a quick insight of what this can do here is a small list

– Have shared services (a service that is shared for all ViewModels)

– Have prioritized Services (have a service priority and MEFedMVVM will pick the appropriate service to be injected)

– Have IContextAware services. These are special UI related services. Basically MEFedMVVM will call InjectContext passing the UI element that requested the ViewModel, so that service can work as a bridge for the ViewModel and the View without any coupling. (This is one of my favorite features)

OK let’s not get side tracked. Were are we?

We have a ViewModel that is an empty class decorated with ExportViewModel and we have two services exported one for runtime and one for design time.

In order to inject the services we need in our ViewModel, we need to state that in the ExportViewModel attribute, like this

   1: [ExportViewModel("VM1", typeof(IUsersService))]

   2: public class TestViewModel {}

This will tell MEFedMVVM to get that service and inject it to the ViewModel. But how can MEFedMVVM inject this in the ViewModel? Well in order to do so your ViewModel must implement an interface called IServiceConsumer. Here is the interface contract.

   1: /// <summary>

   2: /// Defines a service consumer.

   3: /// An entity that has a Service Locator and consumes services

   4: /// </summary>

   5: public interface IServiceConsumer

   6: {

   7:     /// <summary>

   8:     /// Gets the service locator that contains the services 

   9:     /// </summary>

  10:     IServiceLocator ServiceLocator { get; }

  11:     

  12:     /// <summary>

  13:     /// Call to be made when services are injected to the ServiceLocator

  14:     /// </summary>

  15:     void OnServicesInjected();

  16: }

So you will have a ServiceLocator property from where you can get the Services injected from and you need a method called OnServicesInjected which will be called when MEFedMVVM injects the services.

Don’t worry if you do not want to implement the interface yourself we made the heavy lifting for you. You can inherit from BaseViewModel which implements this interface for you. BaseViewModel also implements the INotifyPropertyChanged so you can do PropertyChanged notifications by calling OnPropertyChanged( () => Myproperty); Yes the implementation of INotifyPropertyChanged we used leverages lambdas so that you do not have spelling mistakes when doing property changed notifications 🙂

Back to service injection…. So our ViewModel is not implementing IServiceConsumer or inheriting BaseViewModel; inside the OnServicesInjected you can get the services and get the data you need. Like this

   1: protected override void OnServicesInjectedOverride()

   2: {

   3:     foreach (var item in GetService<IUsersService>().GetAllUsers())

   4:     {

   5:         if (SelectedUser == null)

   6:             SelectedUser = item;

   7:         users.Add(item);

   8:     }

   9: }

So here I am getting the data from the IUsersService that was injected and adding them in a collection which is bound in the View.

So yea finally my designer can see this in Blend

image

This sounded like a lot of work because I went into details of how everything works. But try it and you’ll see how easy it is to do. If its not easy enough get back to me and I really want to hear your feedback.

What if I do not have a service injected but I still want design time data??

Yes, I agree. There are some ViewModels that do not have a service injected BUT they still want design time data. An example of this… Let’s say you have another ViewModel which renders the SelectedUser which the end user selects from the other ViewModel. This ViewModel does not have a service because the data is coming from either from a Mediator callback or from a Property that is bound to some UI…. How can I have Design time data for this ViewModel?

MEFedMVVM let’s you do this as well. All you need to do is implement the IDesignTimeAware. This is the interface

   1: /// <summary>

   2: /// Interface to be implemented by ViewModels that want to do something when rendering in design time

   3: /// </summary>

   4: public interface IDesignTimeAware

   5: {

   6:     void DesignTimeInitialization();

   7: }

The DesignTimeInitialization method will be called on your ViewModel (ONLY AT DESIGN TIME) and inside there you can do what you want in order to have Design Time Data. Here is an example

   1: [ExportViewModel("VM2", typeof(IMediator), typeof(IVisualStateManager))]

   2: public class SelectedUserViewModel : BaseViewModel, IDesignTimeAware

   3: {

   4:     private User selectedUser;

   5:  

   6:     /// <summary>

   7:     /// Gets or sets the selected user

   8:     /// </summary>

   9:     public User SelectedUser

  10:     {

  11:         get { return selectedUser; }

  12:         set

  13:         {

  14:             selectedUser = value;

  15:             OnPropertyChanged(() => SelectedUser);

  16:         }

  17:     }

  18:  

  19:     protected override void OnServicesInjectedOverride()

  20:     {

  21:         mediator = GetService<IMediator>();

  22:         if (mediator != null)

  23:             mediator.Register(this);

  24:     }

  25:  

  26:     [MediatorMessageSink(MediatorMessages.SelectedUser, ParameterType=typeof(User))]

  27:     public void OnSelectedUserChanged(User selectedUser)

  28:     {

  29:         SelectedUser = selectedUser;

  30:     }

  31:  

  32:  

  33:     #region IDataContextAware Members

  34:  

  35:     public void DesignTimeInitialization()

  36:     {

  37:         SelectedUser = new User

  38:         {

  39:             Name = "Marlon", Surname = "Grech", Age = 24

  40:         };

  41:     }

  42:  

  43:     #endregion

  44: }

This will render like this in Blend

image

What if the DataContext is set because I am in a DataTemplate? How can I get Services injected and some design time data as well?

Very well. Sometimes we have scenarios when you have a DataTemplate that has a UserControl inside. This UserControl will still have a ViewModel set as its DataContext but it must not be set from MEFedMVVM ViewModelLocator.ViewModel attached property since the ContentControl or the ItemsControl should be setting the DataContext.

You can still do this with MEFedMVVM! In the ExportService you can have an additional parameter stating that this ViewModel should be “DataContextAware”. Something like this

   1: [ExportViewModel("UserVM", true, typeof(IMediator))]

   2: public class UserViewModel : BaseViewModel, IDesignTimeAware

   3: {

The second parameter passed set to true is where you specify that this ViewModel needs to be “DataContextAware”.

What is this gonna do?

Well at Runtime it will not create an instance of the ViewModel, instead it will wait until the DataContext is set on the UIElement. When DataContext is set, it will inject the services that you requested in the ExportViewModel.

At DesignTime it will create the ViewModel instance and inject it in the DataContext of the UI element so that you can still design your UI seamlessly.

Conclusion

These are only some of the features that MEFedMVVM has to offer. We are working on expanding more functionality. We are also working hard to test as many scenarios as possible but without your feedback and help we cannot cover all of them.

Please let us know if you encounter any issues so that together we can continue building an awesome and easy to use library, and have loads of fun creating cool WPF and SL applications 🙂

Download the source

http://mefedmvvm.codeplex.com/

Peace