Browse by Tags

All Tags » Managed Extensibility Framework   (RSS)

I've been building enterprise applications for more than a decade now, and have specialized in Silverlight line of business applications for the past several years. The term "enterprise" seems to inspire images of complex, large, difficult-to-maintain software systems but a well-written system doesn't have to suffer from the extra complexity. One question I receive over and over again is what a good resource is to learn best practices for building Silverlight applications that target line of business. The market is just now starting to come out with books and tutorials that address these topics but for the longest time you had to scour to find most of your information in blog posts or tweets. I decided to take on two projects to fill two very specific gaps and I'm excited to share the details with you in this blog post.

The first project reaches past Silverlight and addresses a framework I believe was game-changing when introduced with .NET 4.0: the Managed Extensibility Framework (MEF). I partnered with Addison-Wesley to produce a LiveLessons video series and ended with over 4 hours covering the fundamentals of MEF.

I learned about the Managed Extensibility Framework (MEF) when it was in early preview. The first project that I used it for that went to production was the 2010 Winter Olympics in Vancouver. It helped our team build out reporting modules quickly and easily. It did not take long for me to discover how powerful it was for Silverlight applications. I have since used it in projects ranging from SharePoint WebPart integration to the slate application our company developed for Rooms to Go.

One of the more popular posts on my blog was the 10 reasons to use the Managed Extensibility Framework article I wrote in April of 2010. MEF is also the foundation for the MVVM framework I wrote and released as the open source project Jounce. While I've found it to be a powerful framework that is bundled as part of the runtime (it's not a third-party add-on, but shipped with everything else when you installed .NET and Silverlight) there has been one nagging problem: lack of documentation.

I can't tell you how many times I've been asked where I learned about the framework (through blog posts) or where I found best practices (trial, error, and talking to others who used the framework) and what the best book about MEF is to buy (I don't know). So when Addison-Wesley (Pearson) approached me about a video tutorial as part of their LiveLessons Series to cover fundamentals of the framework, I was ecstatic.


For several months I spent a few hours after work and over the weekends building sample projects, recording screen casts, and putting together a curriculum that I felt would provide developes with everything they need to know to be proficient with using MEF. I wanted to be sure you learned when to use it and when not to use it. My goal was to share all of the problems I've faced building enterprise software that MEF was able to solve, and package the recipes I've used to solve common problems.

The end result is the Fundamentals of the Managed Extensibility Framework. Feel free to click on the link and take a peek at the product, but I also want to be sure you know about the free sample that covers Lesson 7 about Silverlight. It is an excerpt from the full lesson but will give you insights into how the screen casts and lessons work to decide if it's presented in a way suited to your learning style. I am very excited about what I was able to cover. Click here to watch the free sample.

The program starts by guiding you through a reference application that uses most of the features of MEF, including discovery, lifetime management, extensibility, and metadata. I then go into the details of imports and exports, parts, catalogs, and containers. I focus specifically on discovery, extensibility using a plug-in model, and provide samples for understanding how MEF manages the lifetime of objects. I cover collections, recomposition, composition batches, and debugging then focus on both flavors of metadata (weakly and strongly typed). I have a full lesson dedicated to the specific uses of MEF in Silverlight, and conclude with a set of recipes that demonstrate common problems I've solved in real world projects using MEF.

You can also watch the course as part of your Safari books online subscription.

I hope this helps fill a much-needed gap in documentation and tutorials about the Managed Extensibility Framework. For those of you who do invest in the tutorial, I would greatly appreciate you sharing your honest comments and feedback using the comments at the end of this post. That will help me learn how to make it better and more importantly help others decide what value they may gain from the tutorial . Watch the 20-minute sampler here and take a look at the full package here. Access the tutorial through Safari Books online at this link.

Jeremy Likness

After having worked on several major projects that integrated the Managed Extensibility Framework, I thought it might be beneficial to share a retrospective on how it was used what value it provided. These are all ways MEF helped my team build modular Silverlight applications.

Unlike my earlier post that covered 10 Reasons to use the Managed Extensibility Framework, this is more of an inventory of actual, specific use cases it has been implemented in real world projects, sometimes referred to as "the wild."

Inversion of Control/Dependency Injection

This was perhaps the easiest decision to make. None of these applications had any requirements for more advanced inversion of control or dependency injection than what MEF offers out of the box. Because we were using it for other reasons, and because it is now native to the framework, it was the logical choice to solve this problem. In most cases, it was as simple as defining the interface, importing it where needed and exporting it where satisfied. Other, more specific cases are described below.

Configuration

Configuration was very important and is easy to facilitate with MEF. I included this as a sub-item under IoC because it really is a side effect of inversion of control. By defining a configuration interface, all code could then reference that interface and testing could mock the values. The main application service implemented the configuration and used a combination of compile-time constants as well as parameterized values to load these. Any consumer, application-wide, then simply needed to import the interface to have access to these variables, even from dynamically loaded modules that had no concrete references to any of the assemblies that configuration lived in.

Logging

Logging is another indirect benefit of the IoC pattern that just happened to be implemented with MEF. We created an interface for logging that was satisfied by a logger and maintained the discipline of avoiding "Debug.WriteLine" and instead writing to the log file with severity, source, and additional information. This separation of concerns allowed us to use a simple logging mechanism in the beginning (it could simply write to the debug window) but gave us the flexibility to add service calls, store logs to isolated storage, or otherwise manage the logging transaction easily from one place without changing any of the rest of the application.

Region Management

Prism 4.0 has an excellent region management framework, so I want to be clear that I have nothing against it and am not about reinventing the wheel. For this project, we only had a few specific types of regions defined, so it was more lightweight to use a more specific version.

Essentially, region management consisted of a few pieces. There was an interface for a region adapter that is scoped to a type of container (Grid, or ContentControl, etc). To implement a new region adapter was as simple as inheriting the interface, adding metadata to describe the target container it would support in a MEF export, and then writing the specific events which including registering (pointing a view to a region), activating (making the view appear in the region) and deactivating (making it go away). Some of this involved manipulation of content or child elements but much of it was driven by the Visual State Manager.

An attached property defined a container as a region, and metadata on a view defined what region that view targeted. The region manager aggregated all of these parts and coordinated between them. If I needed a view activated, the region manager would use the chain of responsibility pattern to find the region adapter that owned the view, then ask it to bring it to focus.

[RegionManagerExport(typeof(ContentControl))]
public class ContentRegion : RegionBase<ContentControl>

Read MEF instead of PRISM Part 2 for a detailed explanation of building custom region management, and see Advanced Silverlight Applications using MEF for an example framework.

Service Integration

A common pattern in line of business applications is to have different types of models or business domain objects that can have some common operations performed against them, such as CRUD (create, read, update, delete). For this reason, I was able to create an abstract IServiceFor<T> style interface and define some common functions. Implementations of the contract would export themselves explicitly, and a service router handled mapping the entities to the service handler for the entity.

What this meant is that I could build a view model for an entity and simply request a service from the service router for the entity type and perform all of my generic operations without worrying about how the service was implemented. I could easily stub the service while developing until the endpoints were actually created. Some services actually interacted with isolated storage while others carried messages over the wire: these were all abstracted from the view model and brought together with MEF.

[Import]
public IServiceLocator Locator { get; set; }

var service = Locator.GetServiceFor<T>();

Messaging

Messaging is a very important aspect of any system. For example, consider having a filter view model with filter data that can be applied to other view models. How do these other view models keep track of when the filter changes, or access the filter data?

In this project, we handled messaging in two ways.

View Composition

Something like a filter, even when globally applied, can be considered a part of the view model that use it. It does not make sense by itself, but when it is composed as part of another view model, it has context and use. MEF was extremely helpful with this pattern because any view model that needs access to another could simply import it:

[Import]
public OtherViewModel Other { get; set; }

Of course, that still doesn't allow us to know when it changed, unless we subscribe to the property changed event. That may make sense in some circumstances, but often there are messages so important that many different parts must listen to them. For this purpose, we used the EventAggregator pattern.

Event Aggregator

The event aggregator I used was based on this post, which describes an event aggregator based on Reactive Extensions (Rx). I factored it to work with Silverlight and it worked like a charm.

One common pattern was messages that caused the application to change. For example, a new filter or a new selection item. I created a special class for carrying these messages. It held the type, the payload, and an enumeration. If I wanted to publish a selection event, for example, I could create this class and place the item selected, it's type, and the enumeration for "select" and publish that.

Any "listener" can then filter like this:

var query = from evt in EventAggregator.GetEvent<MyEntityEvent>()
   where evt.Type.Equals(typeof(MyWatchedEntity)) && 
         evt.Action.Equals(Actions.Select)
   select evt.Cast<MyWatchedEntity>(); 

query.Subscribe(myEntity=>{//do something});

Dynamic XAP Routing

Dynamic XAP loading is important in Silverlight applications because it is downloaded from the web and resides on the user's machine. There are two major concerns: the first is the load time for the application, and the second is the memory footprint and impact to the user's machine. Dynamic XAP loading helps by breaking the applicatin into modules. A module is loaded only when requested. Therefore, the initial application loads faster with a smaller memory footprint and grows gradually as modules are exploited.

The challenge some frameworks have is how and when to trigger the module load. I've become fond of a concept I call "dynamic XAP routing." The concept is simple: I tag views with names, either a friendly name or the full namespace. In my core or "infrastructure" project, I have a set of global constants. While the current module may not know about a view, the constants can represent the view. Another set of constants describes the XAP files that are available.

With these two pieces of information, I can then dynamically route via a deployment service that uses deployment catalogs to load modules. A route contains a pointer to a view and the XAP file the view lives in, and is exported by whatever module may need to load that view. When the view is requested, the view manager first checks to see if a route exists. If it does, it asks the deployment service to dynamically load the XAP and defers raising the navigation event until the dependent XAP file is loaded. This makes it easy to abstract navigation from the modules, because any area in the application simply requests the view, and the framework takes care of either navigating to the view, or loading the XAP file and then navigating.

View Model Routing

A common concern with using MVVM is how to bind the view model to the view. In the frameworks I use, there is not a one-to-one mapping because some view models might service multiple views. The view model never really knows about the view(s) it is attached to, but the views depend on the view model (consider it the "binding contract" for the view). Views are exported by type or tag with a target region, and view models are also exported with a view model tag.

Next, I have a simple route object that contains two tags: a view tag, and a view model tag. Whether the view exports this tag, or a separate "routing" class does, these exports are then all managed by a centralized router. The router is able to pull views, and because everything is lazy-loaded, determine if the view needs the view model bound. Conversely, the view model can also be created for the first time or referenced.

The result is that the view and view model binding is completely decoupled - it is described elsewhere in the application. What it also means is that the routing system knows when a view is being shown for the first time, so it can call methods on the view model both the first time it is created, and each time a view is active. This allows my view models to respond to housekeeping that may be required before binding to the view again, without having a dependency on the visual tree.

[ExportAsViewModel(typeof (DialogViewModel))]
public class DialogViewModel : BaseViewModel

...

[ExportAsView(typeof(MyDialog),Regions.DialogRegion)]
public partial class MyDialog
{        
    public MyDialog()
    {
        InitializeComponent();            
    }     
  
    [Export]
    public ViewModelRoute DialogBinding
    {
        get
        {
            return ViewModelRoute.Create<DialogViewModel, MyDialog>();
        }
    }
}

Take a look at View Model binding with MEF and Yet another MVVM Locator pattern for more on this.

Decoupling Views

There are many cases when you may need to map to a type of view but don't know what the view will be before hand. For example, consider a navigation framework that depends on view types (see the next section). When the view is in a dynamic XAP file that isn't loaded, there is no way to directly reference the time. MEF was very useful in "late-binding" types, that is to say, I could import a property for a type using a tag ("MainView" or "DashboardView") and then export the tag when the view was defined somewhere else. This allowed the idea of interacting with a view to be completely decoupled from the actual view type.

Navigation

MEF provided a very flexible navigation framework. I wanted something composable, such that a "navigation event" wasn't limited to a "page" in the application, but rather a view - and views often are nested inside of other views.

The navigation works in conjunction with the view model router to synchronize changes with the view model. In the framework I developed, the MEF-enabled event aggregator simply raises a view navigation event which encapsulates the type of a view and a flag for activation or deactivation. The router, which has imported all views and view models, finds the view, talks to the region manager to swap it out, and if it is active will also call the appropriate method on the view model.

Navigation became incredibly simple because the concept of a dialog or page or even wizard step is reduced to a simple navigation event. The idea of "pop-up" is an implementation detail abstracted from the event itself, and a view model simply raises the request for a view for navigation to happen and doesn't have to worry about view models, regions, or any other nuances of the navigation itself.

Authorization

Authentication and authorization are required for most line of business applications. Typically the user has properties such as roles and credentials that are checked for access and authorization to various areas of the appplication. MEF makes it easy to carry these credentials because the user construct can be exported as either a concrete object or contract, and then imported and queried by any area of the application that requires access to the credentials and user properties.

Commands

Certain commands can be tightly coupled to the user interface, and others might exist in modules not yet referenced. For example, a "home" command or an "expand" command requires a navigation event that is aware of the target for the navigation.

Late-binding Commands

MEF helped handle this scenario by allowing commands to be exported and imported. In some cases, the view model would import the command based on a pre-defined tag (such as a "home" tag) even if the "home" view is in a different module. The module, when loaded, would export the appropriate command and it then becomes avaiable for binding from the view model even though the command was "late-bound" meaning it did not become available until the child module was loaded.

[Import(Contracts.COMMAND_GOHOME, AllowDefault = true)]
public DelegateCommand<object> HomeCommand { get; set; }
...
[Export(Contracts.COMMAND_GOHOME)]
public DelegateCommand<object> HomeCommandExport
{
    get
    {
        return
            new DelegateCommand<object>(
                obj => EventAggregator.Publish(typeof (HomeView).AsViewNavigationArgs()));
    }
}

Global Commands

Some commands are global by nature and instead of creating dozens of local copies per view, make sense to be accessed as a single, global construct. Global commands be exported and then imported wherever they are needed so a global copy is used, rather than creating multiple local instances. Again, as with the "home" example, view models can expose a "home" command before having knowledge of the assembly/module that contains the command, and MEF simply imports the command when it becomes available.

Read Sharing Commands with MEF for more.

Chain of Responsibility

The chain of responsibility pattern is a powerful way to handle common messages that are processed differently based on the message signature. I used MEF to provide a "handler" mechanism that defined a standard contract that would consume certain message types. Each handler would export the contract along with metadata described what messages the handler could process. A central "router" would then import the handlers, listen to the message, and pass the message to the appropriate handlers until one indicated it had successfully processed the message. This, coupled with global commands, provides a very powerful level of extensibility to the application.

For example, consider a "print" command that is globally exposed throughout the applicaton but bound to the data element being printed. Multiple handlers are registered to the print interface that know how to process different types of data objects. When the handler that manages the target object is called, it formats the data in a printer-friendly format and sends the output to the printer. Handling a new type of data is as simple as building a new handler and then exporting the print contract.

Factories with Dependency Resolution

Many classes have multiple layers of dependencies. Consider a composable view where a list of items is presented, and each item is exposed via a bound view model that has dependencies to the event aggregator, service bus, and other contracts that are imported using MEF. MEF makes this scenario simple and straightforward to handle via the ExportFactory keyword. When spinning through a list of data objects, a view model can be created on the fly using the export factory that features full dependency resolution, from handlers to global commands. The data is attached and then the view model bound to the child view with all dependencies resolved via MEF.

Design-Time Friendly Views

Design-time friendly views are extremely important when working with the design team in parallel. MEF made it very easy to build a design-friendly framework because the runtime view models would be bound via the MEF constructs while the design-time view models are bound directly in views using the d:Design and d:DesignInstance attributes. By isolating MEF-specific initialization code using the IPartImportsSatisfied contract, the views and view models remained designer-friendly and would not execute any code reserved for the run time version of the application.

See Design-time Friendly View Models with MEF for more.

Validation Engine

Validation engines typically expose different validation rules that result in rule violations. MEF made it simple and easy to build an engine that was both flexible and extensible. Each validation rule is exported using the contract for the rule. The engine would import all rules, and then provide access via a fluent interface. Read fluent validation with MEF and PRISM to learn more.

Unit Testing

MEF was critical in the success of unit testing because all dependencies were exposed by contracts that MEF imported. For testing, the MEF initializer simply isn't called, allowing the test system to initialize the dependencies using test mocks and stubs. Take a look at using Moq with Silverlight for advanced unit tests.

Conclusion

Obviously, many of these examples could be easily handled using frameworks other than the Managed Extensibility Framework. The framework has the advantage of being included in the language run-time: it's not a third-party, out-of-band release, but a fundamental part of both the .NET 4.0 and the Silverlight 4.0 CLR. Based on my experience building very large line of business Silverlight applications, MEF not only made it easy to break those applications into modules and parts, it also accelerated development time by providing so many features "out of the box," especially the ability to tag exports with meta data and import multiple items for the same contract. Hopefully this will not only provide you with some ideas about how to use MEF in your own applications, but also demonstrates how MEF is being used effectively in production line of business applications.
Jeremy Likness

Published another quickstart. This is an introductory quickstart for the Managed Extensibility Framework, and is similar to the previous one except that it is specific to Silverlight. You can take a look at the article and watch the short video by clicking here.

Jeremy Likness

I've been doing quite a bit with Reactive Extensions (Rx) for Silverlight lately. One idea that I keep exploring is the concept of creative intuitive sequential workflows for asynchronous operations. You can read about my explorations using Wintellect's own Power Threading Library in this post along with a simple solution using an interface and enumerators in part 2 of that series. I'm tackling the problem from a different angle.

First, my disclaimers: this is more of an exploratory, "Here's what can be done" post. Please don't take this as best practice or guidance, but more of another way of looking at the solution as well as an opportunity to dive deeper into Reactive Extensions. Also understand I am by no means an expert with Rx so I welcome feedback related to this experiment.

The concept is straightforward: there are often times we want an asynchronous set of operations to perform sequentially. Perhaps you must load a list from a service, then load the selected item, then trigger an animation. This can be done either by chaining the completed events or nesting lambda expressions, but is there a cleaner way?

To me, a cleaner solution would make it easy to see what happens sequentially, and also easy to fire the sequence. If it becomes too complex to force the sequential workflow, it buys us nothing from the traditional methods of wiring into completed events or nesting lambda expressions.

So, I started with the idea of having a helper object that I could feed operations to in sequence, then fire it off. What would that look like?

First, I made an interface to keep track of operations as they run and complete. This is by no means a perfect design but for now it's a sort of "recrusive container" for work done. The interface looks like this:

public interface ISequentialResult 
{
    List<ISequentialResult> Results { get; set; }
    object Value { get; set; }        
}

The result is simple: it aggregates all previous results, and contains a pointer to whatever is processing the current action in the sequence. Simple enough. Now on to a base class:

public abstract class BaseResult<T> : ISequentialResult 
{
    protected IObserver<ISequentialResult> Observer { get; set; }

    protected BaseResult(IObserver<ISequentialResult> observer)
    {
        Results = new List<ISequentialResult>();
        Observer = observer;
    }

    public List<ISequentialResult> Results { get; set;}

    public object Value { get; set; }       

    public T TypedValue
    {
        get { return (T) Value; }
        set { Value = value; }
    }
}

The base class does a little more for us. First, it introduces the concept of an IObserver. The observer is simply a class that receives notifications, and the type is the type of the notification. In this case, we allow for a derived type that will create the observer as well as take our "object" value and type it to a specific value. You'll see how the observer works with our sequences in a bit.

Next, I created three implementations. One is just a default that does nothing, and the other two handle Click events and Storyboard interactions. Let's take a look at the handler for storyboards:

public class StoryboardResult : BaseResult<Storyboard>  
{
    public StoryboardResult(IObserver<ISequentialResult> observer, Storyboard sb) : base(observer)
    {
        TypedValue = sb;
        sb.Completed += SbCompleted;
        sb.Begin();
    }

    void SbCompleted(object sender, EventArgs e)
    {
        TypedValue.Completed -= SbCompleted;
        Observer.OnNext(this);
        Observer.OnCompleted();
    }       
}

You'll notice a few interesting things. We take in the story board, wire into its Completed event, then fire it off (we could have changed the interface to have an Execute method to give this more flexibility). The story board completion is the important piece to consider. First, the event is unhooked. Then, we pass the result to the observer. The observer is waiting for ISequentialResult notifications. We provide it with one, but only after the story board is completed. We also tell the observer "we're done" (an observer can listen for multiple push notifications, so we could have created a handler that never completed, or one that aggregated multiple storyboards and only completed when all story boards were done).

With that in mind, take a look at the Click handler:

public class ClickResult : BaseResult<ButtonBase>
{
    public ClickResult(IObserver<ISequentialResult> observer, ButtonBase button) : base(observer)
    {
        TypedValue = button;
        button.Click += ButtonClick;
    }

    void ButtonClick(object sender, System.Windows.RoutedEventArgs e)
    {
        TypedValue.Click -= ButtonClick;
        Observer.OnNext(this);
        Observer.OnCompleted();                 
    }
}

This is very similar to the storyboard. There is nothing to "kick off" but instead this result simply registers itself whenever the target is clicked. Why would we do that? I'll get to the example in a minute.

The most interesting part of workflow is the sequencer itself. This is the class that will manage the asychronous events and coordinate them. The key is that while they run sequentially, they also run asynchronously so there is no blocking.

Here is the sequencer class:

public class Sequencer : IDisposable 
{
    private IDisposable _sequence;
    private ISequentialResult _result;

    private readonly List<Func<IObserver<ISequentialResult>,ISequentialResult,ISequentialResult>> _sequences
        = new List<Func<IObserver<ISequentialResult>, ISequentialResult,ISequentialResult>>();

    public void AddSequence(Func<IObserver<ISequentialResult>, ISequentialResult,ISequentialResult> sequence)
    {
        _sequences.Add(sequence);
    }
        
    public void Run(Action<Exception> exception, Action<ISequentialResult> completed)
    {
        _sequence = Observable.Iterate(_Sequencer)
            .Subscribe(
                next => { },
                exception,
                ()=>completed(_result));
    }

    private IEnumerable<IObservable<Object>> _Sequencer()
    {
        var x = 0;

        _result = new DefaultResult(null) {Value = this};

        while (x (
                observer =>
                    {
                        var newResult = sequence(observer, _result);
                        newResult.Results.Add(_result);
                        newResult.Results.AddRange(_result.Results);
                        _result = newResult;
                        return () => { };
                    }
                ).Start();

            yield return step;                

            x++;
        }

        _result.Results.Add(_result);
    }

    public void Dispose()
    {
        _sequence.Dispose();
    }
}

There's a lot going on here, so let's break it down.

First, you'll notice two references: one to a disposable object, and one to a result. More on those in a bit.

The list may seem confusing at first, but it's only because of all of the type specifiers. Each "step" is represented by a function. The sequence will call the function with an observer and the previous result, and expect to get a new result back. Think of it as "here's who is watching, and what happened the last time ... now give me what you have."

A method is provided to add these steps to the sequence.

The run method is interesting. This is where we set up our disposable reference because we're creating a long-running observer that we want to dispose of when the sequence itself is disposed. The iterate function takes a list of observable sequences and observes them sequentially. We provide an enumerator that feeds the observable sequences, and for each sequence in the "outer loop" (the main algorithm that drives the sequential work flow) we simply drive through the collection. If an exception is encountered, we'll call back with the exception. When completed, we call back with the final result.

To better understand what's going on, take a look at the enumerator. For each iteration, we create a new observable stream. We call the function I mentioned earlier and pass the observer in. When we receive the result, we stack it recursively and store it, then iterate to the next in line. The yield statement ensures the sequential operation completes (when we call the OnCompleted in our result) before the next step begins.

That's the complicated part: setting up the core framework. Now comes the easy part: plugging into it.

In the XAML I placed a large red rectangle. There are three storyboards tied to the rectangle. One changes the colors, one shrinks it, and one twists it using the plane projection. There are also three buttons. One button kicks off the story boards. One button kicks off a sequential workflow that will run the story boards in order. The final button resets the story boards by calling Stop on them.

Let's have some fun. First, kicking off the story boards is simple enough:

private void Button_Click(object sender, RoutedEventArgs e)
{
    StoryTwist.Begin();
    StoryShrink.Begin();
    StoryColor.Begin();
}

The reset button is also easy:

private void Button_Click_2(object sender, RoutedEventArgs e)
{
    StoryTwist.Stop();
    StoryShrink.Stop();
    StoryColor.Stop();
}

Now for the sequential storyboards. This is where things should get easier for us. Instead of having to wire in several completed events or nesting lambdas, let's see what it looks like to run them in order using our sequencer:

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    if (_sequence != null)
    {
        _sequence.Dispose();
    }

    _sequence = new Sequencer();
    _sequence.AddSequence((o, r) => new StoryboardResult(o, StoryColor));
    _sequence.AddSequence((o, r) => new StoryboardResult(o, StoryShrink));
    _sequence.AddSequence((o, r) => new StoryboardResult(o, StoryTwist));
    _sequence.Run(ex => MessageBox.Show(ex.Message),
                    result =>
                        {
                            foreach (var storyboard in
                                result.Results.Select(sequence => sequence.Value).OfType<Storyboard>())
                            {
                                storyboard.Stop();
                            }
                            _sequence.Dispose();
                            _sequence = null;
                        });
}       

So what's going on? If we have a previous sequence running, we dispose it so we can start fresh. Then, we simply add each story board in the order we want it to fire (the observer is provided to us by the sequencer). Finally, we run it. If there is an error, show it. When the sequence is done, we iterate the results and find any result that was a story board and call the "stop" method. This means after the sequence completes, it will automatically restore the rectangle to its original state.

Finally, to show just how powerful it is to drive sequential workflows without blocking, I added one more method:

private void _WaitForThreeClicks()
{
    _buttonSequence = new Sequencer();
    _buttonSequence.AddSequence((o, r) => new ClickResult(o, ResetButton));
    _buttonSequence.AddSequence((o, r) => new ClickResult(o, ResetButton));
    _buttonSequence.AddSequence((o, r) => new ClickResult(o, ResetButton));
    _buttonSequence.Run(ex=>MessageBox.Show(ex.Message),
        result=>
            {
                MessageBox.Show("You clicked the Reset button 3 times!");
                _buttonSequence.Dispose();
                _WaitForThreeClicks();
            });
}

This is a fun method. It literally creates three sequences, all "waiting" for the reset button to be clicked. After the sequence completes, we show a message indicating that 3 clicks happened, then restart the sequence recursively. I'll call it the first time just after IinitializeComponent:

public MainPage()
{
    InitializeComponent();  
    _WaitForThreeClicks();
}      

There you have it! When you run the code, you'll get this:


Notice that you can keep clicking the sequence to start it over: there is no blocking. And whatever order you decide to click on other buttons, the reset button always faithfully shows a "3 click" message on the third click.

You can download the full source code for this solution here.
Jeremy Likness

I've been working with the Reactive Extensions (Rx) library quite a bit lately and am very impressed. While it is a new way of thinking about services, it certainly makes life much easier. In this example, I'll show you a way to simplify your web service calls using Rx. In fact, even if you don't use Reactive Extensions, you may benefit from the proxy wrappers that I'll describe.

I'm assuming you are familiar with Silverlight, web services, and have some exposure to the Managed Extensibility Framework. You'll also want to make sure you've got the latest version of Rx for Silverlight 4.

Let's get started! First, create a new Silverlight 4 Application. Keep all of the defaults: we do want a web project, but we aren't using RIA.

The Service: Server Side

Let's create a simple calculator service. Sure, it is a simple example, but it will make it easier to focus on the details of Rx rather than puzzling over a more complex web service example.

Create a new service and call it "Calculator." Just place it in the root of the web application. Create a contract and implement it, so that your service ends up looking like this:

namespace RxWebServices.Web
{
    [ServiceContract(Namespace = "http://csharperimage/")]
    public interface ICalculator
    {
        [OperationContract]
        long Add(int operand1, int operand2);       
    }

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class Calculator : ICalculator
    {
        readonly Random _random = new Random();

        public long Add(int operand1, int operand2)
        {
            Thread.Sleep(TimeSpan.FromMilliseconds(_random.Next(1000) + 50));
            return operand1 + operand2;
        }        
    }
}

Notice I built in a delay. This is important to see how Rx helps us handle the asynchronous nature of web service calls.

Go ahead and hit CTRL+F5 to build and run without debugging. This will set up the service end point for us to grab in Silverlight. Now, in your Silverlight project, let's set some things up.

The Service: Client Side

First, we want to add some references to both Reactive Extensions (Rx) and the Managed Extensibility Framework. Below, I've highlighted the references to add:


Now we can add our service reference. Right-click references, choose "Add Service" and select "Discover Services in Solution". You should be able to select the calculator service. Put it in the namespace "Calculator Service" as depicted below.


Making Things Easy: ServiceProxy

Services can seem complex, but with the factory patterns provided by the framework and the support of relative paths, abstracting the creation of an end point is easy. I like to create a proxy class thas manages the end points for me. In this example, I store the end point as a constant. However, you can easily make it a parameter for your Silverlight application and construct it on the fly. All my "consumer" really cares about is the service contract, not the details of how to wire in the service endpoint. So, let's make it easy. Take a look at the following class. The class itself is never instanced directly, but it will export the service contract so that wherever I import it, I'll have a fully wired version of the proxy ready to use.

Create a folder called "Implementation" and add "ServiceProxy.cs". Your class will look like this:

namespace RxWebServices.Implementation
{
    public  class ServiceProxy
    {
        private const string CALCULATOR_SERVICE = "../Calculator.svc";
        private const string NOT_SUPPORTED = "Type {0} not supported";                

        private static readonly Dictionary<Type, Uri> _serviceMap
            = new Dictionary<Type, Uri> {{typeof (ICalculator), new Uri(CALCULATOR_SERVICE,UriKind.Relative)}};

        public static T GetProxyFor<T>()
        {
            if (!_serviceMap.ContainsKey(typeof(T)))
            {
                throw new TypeLoadException(string.Format(NOT_SUPPORTED, typeof (T).FullName));
            }

            return
                new ChannelFactory<T>(new BasicHttpBinding(), new EndpointAddress(_serviceMap[typeof (T)])).
                    CreateChannel();
        }

        [Export]
        public ICalculator CalculatorService
        {
            get { return GetProxyFor<ICalculator>(); }
        }
    }
}

Take a look. We are mapping the service contract to the end points. In our case, it is relative to the site serving the Silverlight application. Because the application is in ClientBin, we back up one level to access the service. Note this will work just as easily for a service hosted somewhere else: I would simply specify a relative or absolute uri. We only have one service, but the dictionary makes it easy to map multiple ones. The export uses the channel factory to generate an instance and return the client.

Our Internal Contract

I rarely let the rest of my application concern itself with the details of the service. Any other area of my application is simply asking for results based on input, regardless of how it is obtained. Therefore, I'll create a very light contract for the calculator service internally - one that is easy to mock and test.

Create a folder called "Contract" and add one interface, ICalculatorService. The interface looks like this:

namespace RxWebServices.Contract
{
    public interface ICalculatorService
    {
        IObservable<long> Add(int operand1, int operand2);
    }
}

Here is where things get interesting. You should be familiar with IEnumerable which we'll call a "pull" sequence of elements: you pull the values from the iterator. With Reactive Extensions, we invert this using IObservable to create a "push" sequence. With the push sequence, you subscribe and receive an event (pushed to you) when an element is available. In this case, we'll subscribe by sending in two operands, and wait to be pushed the result when it comes back.

Wrapping the Service

Now we've got a service proxy and an interface. Let's satisfy the contract. I'll show you the code, then explain it. Under the implementation folder, create a Calculator.cs class and wire it up like this:

namespace RxWebServices.Implementation
{
    [Export(typeof(ICalculatorService))]
    public class Calculator : ICalculatorService, IPartImportsSatisfiedNotification
    {
        [Import]
        public ICalculator CalculatorProxy { get; set; }

        private Func<int,int,IObservable<long>> _calculatorService;            

        public IObservable<long> Add(int operand1, int operand2)
        {
            return _calculatorService(operand1, operand2);
        }

        public void OnImportsSatisfied()
        {
            _calculatorService = Observable.FromAsyncPattern<int, int, long>
                (CalculatorProxy.BeginAdd, CalculatorProxy.EndAdd);
        }
    }
}

Let's break it down. First, you'll notice we import the calculator service. This is the actual proxy we set up in the previous class. When the import is satisfied, we use a helper method provided by Rx to convert the asynchronous call into an observable list. The FromAsyncPattern takes in the types of the inputs, followed by the type of the output. It creates a function that, when called, returns an observable list of the results. In this case, we cast it from the beginning call to our calculator service to the return call. This is the way we take the asynchronous call and turn it into an observable list.

When we actually want to use the method, we call the function with the inputs, and receive the output as the observable. Thus, we do all of the conversion internally, hide the implementation details, and just return a stream that can be subscribed to in order to fetch the results.

Take a look at the signature for the actual service:

private interface ICalculator
{
    IAsyncResult BeginAdd(int operand1, int operand2, AsyncCallback callback, object asyncState);
    
    long EndAdd(IAsyncResult result);
}

To use Rx, we want a function that takes all of the inputs up until the AsyncCallback parameter, and returns an observable list of the return value. In this case, our two inputs are int, and it returns a long, so our function signature is Func<int,int,IObservable<long>>. By using these same types on the FromAsyncPattern extension method, Rx will return us the appropriate function and expect a pointer to the methods to start and the end the call.

Fibonnacci Sequence

Now we can get to the fun part: using the service. We'll use the service two different ways to illustrate how the observable lists work. In the MainPage.xaml, add some rows, a set of buttons, and a stackpanel. Generate code behind for the buttons. It will look something like this:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
        <Button Content=" GO " Click="Button_Click" Margin="5"/>
        <Button Content=" GO " Click="Button_Click_1" Margin="5"/>
    </StackPanel>
    <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" x:Name="MainSurface"/>
</Grid>

Next, let's go to the code behind and wire in the first example. First, we'll add some properties we're going to be using:

[Import]
public ICalculatorService Calculator { get; set; }

private IDisposable _sequence;

private readonly Subject<long> _watcher = new Subject<long>();

private int _x, _y, _iterations;

The first piece is the service, which we import using MEF. When we subscribe to services, we receive a disposable observer. In order to cancel observations in progress and start new ones, we'll keep a reference to this using the _sequence field.

What's Your Favorite Subject?

The subject is interesting. Subjects are used to set up a publisher/subscriber model. The subject here is a long. Anyone with access to the subject can publish (send it a long value) and/or subscribe (receive notifications when values are published). We'll use this to bridge between our UI and the service.

Finally, we've got some local variables to use to keep track of state.

Next, we'll set everything up in the constructor:

public MainPage()
{
    InitializeComponent();

    if (DesignerProperties.IsInDesignTool) return;

    CompositionInitializer.SatisfyImports(this);

    _watcher.ObserveOnDispatcher().Subscribe(
        answer =>
            {
                var grid = new Grid
                                {
                                    Width = answer,
                                    Height = answer,
                                    Background = new SolidColorBrush(Colors.Red),
                                    Margin = new Thickness(5, 5, 5, 5)
                                };
                var tb = new TextBlock {Margin = new Thickness(2, 2, 2, 2), Text = answer.ToString()};
                grid.Children.Add(tb);
                MainSurface.Children.Add(grid);
                _Add();
            });
}

The first thing you'll notice is that if we're in the designer, all bets are off and we drop out. Otherwise, we compose the parts, which gives us our service import. Next, we'll subscribe to our subject. Notice that we don't have any service interaction yet. The subscription basically breaks down like this:

  • I'm interested in the subject with long values
  • When something happens, let me know on the dispatcher thread (as I'm going to do something with the UI)
  • When a long value is observed, give it to me: I'll make a grid as big as the value I received, put some text inside it, add it to the stack panel and then call the _Add method

That's very simple and straightforward. No we can explore the missing method. First, let's kick things off when the user clicks the first button. I want to use the add service to compute a fibonnacci ratio (each number is the sum of the previous two, started with 1 and 1). I'll implement the button click code-behind and add the missing method here:

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (_sequence != null)
    {
        _sequence.Dispose();
    }

    MainSurface.Children.Clear();

    _x = 1;
    _y = 1;
    _iterations = 0;

    _watcher.OnNext(_x);            
}      
  
private void _Add()
{         
    _sequence.Dispose();

    if (++_iterations == 20)
    {
        return;
    }

    _sequence = Calculator.Add(_x, _y).Subscribe(answer =>
                                            {
                                                _x = _y;
                                                _y = (int)answer;
                                                _watcher.OnNext(answer);                                                     
                                            });
}

So the first part should be straight forward. If we had another sequence, dispose it. This will cancel any observations in progress. Clear the surface, initialize our variables, and then call the OnNext function on our subject. What's that? Simple: we just published a number. The subject will receive the number (1) and then push it to any subscriptions. We subscribed earlier, so we'll create a 1x1 grid and call the _Add method.

This method is even more interesting. First, we stop after 20 iterations. No sense in going to infinity. Next, we subscribe to the calculator service. Subscriptions to observable lists are the same as subscriptions to subjects. We're asking to watch for a value, and initiating the "watch" by sending in our first values (1 and 1). When we receive the answer, we shift the numbers to continue the sequence, and then publish the number to the subject.

This allows us to "daisy chain" service calls. We wait until we receive the first answer before we ask the next question. At this point, if you hit F5 (or CTRL-F5) to run it, and click the first button, you should see this:

Note if you keep clicking while it is rendering, it will start over. There will be no "hanging" calls because the calls are daisy chained. We are also not blocking the UI while waiting, or you wouldn't be able to click the button again. You can clearly see the delays on the server as the results are returned.

Here is a simplified overview of what is happening:

Random Addition

Now we'll throw another function into the mix. It's time to set up the second button. For this button, we're going to add two methods. The first is an enumerable that returns nothing but random numbers. It loops infinitely so we obtain as many numbers as we like, and we'll receive them in tuples:

private static IEnumerable<Tuple<int,int>> _RandomNumbers()
{
    var random = new Random();

    while (true)
    {
        yield return Tuple.Create(random.Next(100), random.Next(100));                
    }
}

In the event handler for the second button, add this bit of code:

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    if (_sequence != null)
    {
        _sequence.Dispose();
    }

    MainSurface.Children.Clear();

    _sequence = _RandomNumbers()
        .ToObservable()
        .Take(20)                
        .Subscribe(numbers => Calculator.Add(numbers.Item1, numbers.Item2)
                                    .ObserveOnDispatcher()
                                    .Subscribe(result =>
                                                    {
                                                        var text = string.Format("{0}+{1}={2}", numbers.Item1,
                                                                                numbers.Item2, result);
                                                        var tb = new TextBlock
                                                                    {Margin = new Thickness(5, 5, 5, 5), Text = text};
                                                        MainSurface.Children.Add(tb);
                                                    }));                
}    

This is a little different. First, we're taking the enumerable list of random numbers and turning it into an observable list so the values will be pushed to us. This is just by way of demonstration; we could have just as easily iterated the list with a foreach loop instead. What's interesting here is that I can limit how many I grab with the Take(20) extension. I subscribe like I do to any other observable list, and when I receive the next number pair, I turn around and subscribe to the calculator service to add the numbers for me. Instead of publishing the result to the subject, I'm handling it myself. I observe on the dispatcher thread, then add a text block with the addition statement to the stack panel.

Go ahead and run the application, click the button, and you'll receive output that looks like this:

Observations (Pardon the Pun)

If you run this and click the go button, you might notice something interesting. No matter how many times you click, you get the full sequence of numbers. In other words, if I let 5 numbers come back, then click go, I'll receive a sequence of 35 numbers, not 25.

Even more interesting is if you click the second go button, wait until most (but not all) of the 20 numbers return, then click the first go button. You'll see the screen clear, but you'll receive a few sequences of added numbers before the fibonnacci sequence starts.

What's Going On?

But we disposed of the subscription, right? Not exactly. In this implementation, we always getting the same service subscription. The subscription we cancel is the outer observation. To better understand this, load up a tool like Fiddler and watch the service calls. In the first example, the call is made, there is a delay, it returns, and then the next call is made.

In the second example, however, almost all of the calls are made almost all at once. They return at different rates due to the delays on the server. So, when you start a new sequence, you subscribe to the same service and therefore get to watch the results return that hadn't made it back from the initial calls.

This is important to understand as you are building your extensions, because in some cases you might want a new observable sequence, while in others it makes sense to keep the existing one. It depends on your needs and the desired behavior.

Hopefully this will help open some new doors of understanding about Reactive Extensions!

Click here to download the source code for this article

Jeremy Likness

I've been working on quickstarts for a community team that I'm a member of. The team is called MEFContrib. We write extensions to the Managed Extensibility Framework as well as supporting manuals and documentation. I've been tasked with the quickstarts and as I release them I'll post them for you.

Obviously, a quickstart should be, well, quick, and easy. We also decided quickstarts would be independent so that you can jump into any topic without having to read the prior ones. Today's post is simply a "Hello, MEF" for a quick introduction to using MEF. I will also follow up with a version specifically for Silverlight.

I've embedded the quickstart video below, and you can read the full article (with video included) by clicking here.

Enjoy!

Viewing this content requires Silverlight. You can download Silverlight from http://www.silverlight.net/getstarted/silverlight3.

Jeremy Likness

It is very common to have base classes and interfaces that use generic types to define standard behaviors across business applications. One challenge with the Managed Extensibility Framework is that it doesn't directly support generic exports and imports: in other words, there is no way to effectively do the following:

...
[ImportMany(AllowRecomposition=true)]
public IService<,>[] GenericService { get; set; }
...

While there is a GenericCatalog you can use, I wanted something a little more flexible and specific to the application.

The Example Service

Let's assume we have an example "service" interface that does something to an instance of a type. We define the interface like this:

public interface IService<T> 
{
   void DoSomething(T instance); 
}

The Locator

The goal is to have a composite application that automatically picks up services that support different types of T and a locator that easily gives us the instance we are looking for. The locator looks like this:

public interface IServiceLocator
{
    IService<T> GetServiceFor<T>();
}

This allows us to easily ask for the service, and do something with it:

var service = serviceLocator.GetServiceFor<MyClass>();
service.DoSomething(myInstance);

The problem with the locator is that we don't have a basic "generic" import for the various services, and we'd have to do a lot of dancing with reflection to parse out types as they became available in order to wire them in. In this case, I felt it was easier to come up with an intermediary class to facilitate finding the service.

Hinting Around

I call it a hint because it hints to the locator where to find the right service. The interface for a service hint looks like this:

public interface IServiceLocatorHint
{
    bool ServicesType<T>();
    IServiceInterface<T> GetServiceFor<T>();
}

As you can see, the hint has two methods. One determines whether or not the hint is capable of producing the service for a given type, and the other returns that service. Now, let's assume in a dynamically loaded module we implement the service contract for MyClass using a class called MyService. It looks like this:

[Export]
public class MyService : IService<MyClass> 
{
   void DoSomething(MyClass instance) 
   {
      Debug.WriteLine(instance.ToString());
   }
}

Notice I am exporting the service as the concrete type. Next, I build a simple hint:

[Export(typeof(IServiceLocatorHint))]
public class MyModuleHints : IServiceLocatorHint
{
    [Import]
    public MyService MyServiceInstance { get; set; }
 
    public bool ServicesType<T>()
    {
        return typeof(T).Equals(typeof(MyClass));
    }

    public IServiceInterface<T> GetServiceFor<T>()
    {
        if (ServicesType<T>())
        {
            return (IServiceInterface<T>) MyServiceInstance;
        }

        throw new NotSupportedException();
    }

}

Putting it all Together

Now that we have the service wired by MEF with all dependencies, and the hint wired as well, we can implement the locator class.

[Export(typeof(IServiceLocator))]
public class ServiceLocator : IServiceLocator
{
    [ImportMany(AllowRecomposition = true)]
    public IServiceLocatorHint[] Hints { get; set; }

    public IServiceInterface<T> GetServiceFor<T>()
    {
        var serviceHint = (from hint in Hints 
                        where hint.ServicesType<T>() 
                        select hint).FirstOrDefault();

        if (serviceHint == null)
        {
            throw new NotSupportedException();
        }

        return serviceHint.GetServiceFor<T>();
    }
}

The class is simple. As modules are loaded, the main list is recomposed to include any new hints that were found. When the user requests a service, it simply finds the hint that satisfies the type, then returns the corresponding service.

Using this flexible locator class is as simple as importing it, then asking for the service:

[Import]
public IServiceLocator Locator { get; set; }

public void ProcessClass(MyClass item)
{
   var service = Locator.GetServiceFor<MyClass>();
   service.DoSomething(item); 
}

If you have multiple services in a module, you can easily build a base class that uses a dictionary to register the instances and streamline the methods that check for support and return the instances. The power of MEF is that new services are easily discovered as plugins and extensions are loaded into the main application, and you can basically build an application around what you don't know yet, rather than having to constrain it based upon what you do know.

Jeremy Likness

During my talk about the Managed Extensibility Framework (MEF) at Devscovery this past week, I had two very good questions asked by the audience and promised I'd get an answer.

The first one was about exporting in MEF. I was under the impression that a MEF part could have one export, but I was mistaken. The confusion came from this thread which doesn't question multiple exports, but rather the shared policy (whether there is one export, or multiple instances of an export created). It's one of those cases where I had read that and somehow got it in my head it wasn't supported, and then simply didn't have a reason to need it so I never investigated it further.

So, thanks for the great question.

Answer One: you can export a single class under multiple interfaces. Not a problem. And, depending on your creation policy, you can ensure only one instance is exported, or a separate interface for the different contracts.

The second one was a little more interesting. It was about versioning and DLLs. The question was if I import an assembly that has a part, then update the assembly on disk, can I pull in the new version?

Answer Two: no, you cannot reload a newer version of the assembly when it is updated on disk This isn't a MEF limitation, but part of the CLR itself. If you think about it, you cannot do this without MEF, either. You might overwrite the DLL, but it will not get loaded (if it already is loaded) until you restart the application. Technically, you can unload the entire app domain or launch a new app domain, but you cannot unload the assembly within an app domain.

Wintellect's Jeffrey Richter explains it well in this dot net rocks interview (PDF transcript). He says:

No you cannot and we will probably never offer that feature. If you think about it, if you load an assembly into an app domain and then you start executing code in that assembly, that may cause other assemblies to get loaded into that app domain as well. And then if you unloaded the first one, we don't know to unload all the others that got loaded accidentally, if you will. So that is one of the reasons why we have app domains, is so that you can do this unloading and then all the other assemblies that got loaded as a side effect get unloaded at the same time. And we are probably going to keep that. We have heard that request from many people that if they want to unload an assembly, may be some day we'll add it, but I think it's very unlikely.

Thanks to everyone who attended and hope this answers your questions.

Jeremy Likness

One question I'm commonly asked is, "Why do I need the Managed Extensibility Framework? How do I know when to use it?" In addition to that really being two questions, I'm not sure I can tell you the top ten reasons to use MEF or whether or not it is the right tool for you. Instead, as a hands-on consultant who has been using MEF in production applications since the earlier previews, I can share ten reasons why I've used it in my development projects and prefer it over over other frameworks.

Reason One: It's out of the box.

While much of my work with MEF has been using the previews in Silverlight 3 projects, MEF is not just another side project or add-on. MEF will be part of the .NET Framework 4.0 Common Language Runtime (CLR). Just as we've grown accustomed to using generic lists or sending mail with the SmtpClient class, the Managed Extensibility Framework will be there, in the framework, out of the box. Developers will be able to simply include the namespace and go to work. No additional installs or grief over whether or not to include the bits with the application and worry about versions. It's an intrinsic part of the .NET framework which I believe will lead to fast adoption for the myriad problems it solves. I always prefer to use what is already there when I can, rather than tacking on third-party solutions unless they are absolutely needed.

Reason Two: Dependency injection and inversion of control.

This is the part that seems to confuse people when they ask, "Do we need another Unity?" MEF is far more than a substitute for dependency injection or inversion of control. However, it does manage DI and IoC quite well. With Unity, for example, I had to wire in a bootstrapper and configure the container, then either grab objects from the container to take advantage of constructor injection or explicitly request objects.

In MEF, the parts model makes it far easier in my opinion. I simply make IFoo available:

...
[Export(typeof(IFoo))]
public class Foo {}
...

And then ask for IFoo, and I'm practically done!

...
public class Bar 
{
   [Import]
   public IFoo Foo { get; set; }
}

I find this far easier to set up and manage consistently across large applications than worrying about when/where/how the container has been configured, whether or not I'm using a nested container, and then how to grab the desired implementation.

It also makes testing a breeze. I don't believe in unit testing multiple layers at the same time - if I'm testing Bar, I'm not going to test Foo again. So in this case, I can just set IFoo to a mock object and focus on Bar.

Reason Three: Lifetime management.

By default, imports will provide me with the same (shared) copy of classes that are exported by MEF. I'm not locked into this, however. I can easily override the lifetime of a class using a PartCreationPolicy. This is very important to me because often classes become mangled in order to support patterns like the singleton pattern: you have to hack the constructor and make it private, then supply a public method, and make all of this work in concert with your interface.

With MEF, I simply build a class and don't build lifetime management into the behavior of the class. Should the class know or care if it will live as a single copy, or have multiple copies running around? In most cases, the answer is, "No."

Reason Four: Configuration.

A side effect of lifetime management is that MEF gives me a very easy way to manage configuration information. I've seen it done many ways. In Silverlight, for example, you might be tempted to write a static class or even add properties to the main Application class to hold application-wide configuration data. To me, mangling the application itself in order to support this is wrong.

With MEF, I can simply implement an IConfiguration interface and import it wherever I need it. If I'm writing WPF or ASP.NET code, it's a simple matter in the implementation to parse an app.config or web.config file to load up the values. The consumers of this information, however, don't have to know (and quite frankly, don't care) how it got there. I have a setting for number of threads? Great, I import my IConfiguration and read that property. Done deal.

This is also great for testing, because I can supply an alternate configuration for my test environment.

Reason Five: Factories with dependency resolution.

This ties back to the part creation policies. One powerful feature of MEF is the concept of an ExportFactory. Unlike a direct import, an import of ExportFactory<T> doesn't give me T, but instead gives me a way to create T. This is important if I have a class that might get created multiple times.

If the class has dependencies, such as the configuration information I gave in the previous point, we need MEF to import and satisfy those dependencies. With the export factory, I can do this:

...
[Import]
public ExportFactory<IContract> Factory { get; set; }

public IContract MakeANewContract()
{
   return Factory.CreateExport().Value; 
}
...

Each time I make a new contract, all of the dependencies are wired in for me, so I don't have to worry about loading up the constructor or walking the dependency tree. MEF does it for me. For an example of this, take a look at my blog post Sequential Asynchronous Workflows using Co-routines (the view factory to "make" squares follows this pattern, as it must import the random number service).

Reason Six: ImportMany.

A common pattern in Silverlight and WPF applications is to have a region for some functionality, and then page through multiple controls within that region. For example, a wizard might occupy the main region of the page but actually use four different controls for each of four different steps in the wizard. MEF makes it easy to handle this pattern using ImportMany. I can ask for an IWizard and then retrieve a list of controls that satisfy the interface.

Another example is chain of responsibility and pipeline. The "weak link" in the chain is often that first "bootstrapper" class that has to wire in all of the links in the pipeline or chain of responsibility. The common implementation of this pattern is to have each link process and then conditionally pass processing along to the next link.

With MEF, I can easily import many instances of ILink and then either chain them together or use an iterator or other means to walk through the processes. Adding a new link is as simply as building the implementing, then exporting the class.

These are just a few examples of how powerful the ability to have multiple imports is.

Reason Seven: Strongly typed Metadata.

Of course, you might want to call classes in a particular order. Perhaps you export user controls and use an enumeration to specify where on the screen it belongs. Whatever your needs are, MEF allows you to supply strongly-typed metadata for your exports.

For an example of this, take a look at MEF instead of Prism for Silverlight. There I use the metadata to specify the types of views and regions, then wire them together using the region management pattern introduced by Prism.

Metadata can provide initialization information, routing information, and even priority information. For the Vancouver Winter Olympics, I built a synchronization tool that would scan primary and failover servers for live streaming. The tool generated lists of mismatched and/or missing files so the team at Microsoft could quickly react to ensure the integrity of the failover cluster and guarantee uptime. The tool created an XML document with the changes, then passed the document through a pipeline of modules. One module persisted the file to disk and updated a manifest. Another module would generate a CSV file, and yet another could email the document if certain alert criteria were met. I used MEF to pull in the modules, and metadata to tag the priority (for example, I wanted to persist the file to disk before specifying it as an attachment in the email program, so the module that saved the file had a higher priority than the module that would email it). When I needed another module, such as in testing, it was as simple as building it and exporting it to inject it into the pipeline.

Reason Eight: Extensibility.

MEF is unique in that it is designed specifically for extensibility. Many Dependency Injection/Inversion of Control solutions are designed to help you wire up what you know - "I have this instance, map it to this interface." MEF is designed to help you wire up what you don't know. It is extensible by nature and contains features such as stable composition that ensure your application can safely extend in realtime.

As an example (and for a fast introduction to MEF if this is new to you) take a look at my video, Build a Plug-in Architecture in Under 10 Minutes. I demonstrate building a console application using MEF. After I have the application running, I build a plugin, drop it into the target directory, and show how the application is able to pull in the new plugin in realtime without restarting. Now that's powerful!

Reason Nine: Modularity.

Along with extensibility comes modularity. This is especially important for Silverlight applications. Because these run in the user's browser, developers must take care to minimize the size of the file download as well as the client footprint. You don't want an application that takes 15 minutes to download or maxes out your customer's memory and CPU.

MEF allows for modularity by allowing you to separate functionality into different modules and load them dynamically as needed. This is done via the DeploymentCatalog. Imagine a large application that has ten menu items, but users typically may only go into one. This was the case for our Winter Olympics application that helped the Microsoft team monitor their environment. At any given time they might be pushing a configuration file, monitoring the live streaming servers, or performing other functions within the tool that were not interdependent on each other.

Instead of loading everything and having a huge XAP file, MEF allows you to split your applications into modules that load on demand. Only when the user needs a piece of functionality will their browser download the extension and make it available. This allows them to get up and running faster and conserves resources by only supplying what is needed.

Take a look at MEF instead of Prism for Silverlight Part 1 for an example of dynamic module loading.

Reason Ten: Customization.

Finally, I prefer MEF because it allows for customization. All of the parts are available to extend or customize as needed. Perhaps you are a fan of convention-based configuration and would rather use a provider-based model to wire in dependencies. It can be done.

I develop in Silverlight and am a fan of creating reusable behaviors to avoid duplicating code-behind or overloading view models where it's not needed. With MEF, this is very easy and straightforward. Take a look at Custom Export Providers with Custom Metadata for Region Management as an example. Using metadata, I wanted to take regions and route views similar to how Prism does it. Because MEF is extensible and customizable, I was easily able to build a behavior that would allow me to tag regions and export them with strongly-typed meta data in the XAML.

Of course, the customization doesn't stop there. Take a look at the MEF Visualizer Tool that can be injected into your project and generate DGML to visualize the MEF parts. Now that's powerful!

Conclusion

I'll conclude by saying that I'm very biased toward MEF. For good reason: I've been using it in enterprise applications and it has enabled me to build more composite, extendable, testable, and scalable applications faster and, in my opinion, better. If you're sitting on the fence wondering how MEF compares to other frameworks, I hope this guide will help you decide just how powerful it can be and how it might better fit your needs.

Please share your comments and feedback below. I'd especially love to hear if you are currently working on a MEF project and would like to share how it has helped (or perhaps hindered) you in the process. Thanks!

Jeremy Likness

Over the past few weeks I've been exploring the concept of region management using the Managed Extensibility Framework, and for a good reason. I'm working on a project that has several different regions and controls that must be managed effectively and across the boundaries of dynamic XAP files in Silverlight 3.

Sound like a mouthful? In previous posts I demonstrated some methods for handling region management using MEF. This post is an advanced post and I'm assuming you have the fundamentals of MEF down. If not, I would come back to this post at a later time. You'll also want to be familiar with my previous experiments detailed in this article and another version in this video tutorial.

So the ultimate goal for me is to tag a view with a type, tag a region with a type, then route views to regions and vice versa. This way I can easily add controls (just tag 'em) and regions (again, tag 'em) and have a routing table that handles swapping them in and out for me.

One of the issues in the past has been having to explicitly export the region. In other words, I might have a ContentControl tagged for a particular region. I have to give it an x:Name in the XAML, like this:

...
<ContentControl x:Name="MyName"/>
...

And then export it with my custom attributes like this:

...
[TargetRegion(Region=ViewRegion.MainRegion)]
public FrameworkElement MainRegionExport 
{
   get { return MyName; }
}
...

This assumes I created a custom export attribute with a Region parameter and a base type of FrameworkElement. Where I want to go is here: eliminate the code behind, and tag my regions like this:

...
<ContentControl mef:TargetRegion.Region="MainRegion"/>
...

In the XAML, with no code behind. Can we get there? Of course, this is MEF!

The first step for me is to create to a custom export provider. I spoke briefly about this in an old post: Custom Export Provider for Attached Exports, but that was for static controls. Here, I want to export regions with meta data. The export provider looks like this:

public class RegionExportProvider : ExportProvider
{
    private static readonly Dictionary<ExportDefinition, List<Export>> _exports = new Dictionary<ExportDefinition, List<Export>>();

    private static readonly RegionExportProvider _provider = new RegionExportProvider();

    public static DependencyProperty RegionProperty = 
        DependencyProperty.RegisterAttached(
        "Region", 
        typeof(ViewRegion), 
        typeof(RegionExportProvider),
        null);       

    public static ViewRegion GetRegion(DependencyObject obj)
    {
        return (ViewRegion) obj.GetValue(RegionProperty);
    }

    public static void SetRegion(DependencyObject obj, ViewRegion value)
    {
        obj.SetValue(RegionProperty, value);
        GetRegionExportProvider().AddExport(value, obj);
    }

    private static readonly object _sync = new object();

    public static RegionExportProvider GetRegionExportProvider()
    {
        return _provider;
    }

    public void AddExport(ViewRegion region, object export)
    {
        lock (_sync)
        {
            string contractName = typeof (FrameworkElement).FullName;

            var metadata = new Dictionary<string, object>
                               {
                                   {"ExportTypeIdentity", typeof (FrameworkElement).FullName},
                               }; 

            var found =
                from e in _exports
                where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0
                select e;
            
            if (found.Count() == 0)
            {                    
                var definition =
                    new ExportDefinition(contractName, metadata);

                Debug.WriteLine("Region Export Provider: Add custom export: " + region);

                _exports.Add(definition, new List<Export>());
            }

            metadata.Add("Region", region); 

            var wrapper =
                new Export(contractName, 
                    metadata, 
                    () => export);

            found.First().Value.Add(wrapper);
        }
    }

    protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
    {
        var contractDefinition = definition as ContractBasedImportDefinition;
        IEnumerable<Export> retVal = Enumerable.Empty<Export>();
        
        if (contractDefinition != null)
        {
            string contractName =
                contractDefinition.ContractName;
            
            Debug.WriteLine("GetExportsCore: Request for contract: " + contractName);

            if (!string.IsNullOrEmpty(contractName))
            {
                var exports =
                    from e in _exports
                    where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0
                    && definition.IsConstraintSatisfiedBy(e.Key)
                    select e.Value;

                if (exports.Count() > 0)
                {
                    Debug.WriteLine("Export satisfied.");
                    retVal = exports.First();
                }
                else
                {
                    Debug.WriteLine("Export was not satisfied.");
                }
            }
        }

        return retVal;
    }
}

Let's step through it. First, I need to keep a catalog of my exports. These are unique type definitions and contract names that we are going to satisfied with our custom export provider. I use the singleton pattern because I'm going to double this class as an attached behavior. Probably violating the single responsibility principle here, and could break it out, but let's run with it for now. Sometimes it makes sense to keep the code together for readability and maintainability.

The attached property just takes the type of the region. Because we type it to the enumeration, intellisense will work in the XAML when adding the behavior, which is nice, because it makes it less of a "magic string" for us to use.

The key to note is the setter. When we set the value, we add the export. The export itself is going to be the contract name and the type identity. This is why we add the first bit of meta data, the ExportTypeIdentity, and then see if we've already made an entry or not. If not, we add a new entry with an empty list of the actual exports.

Adding the exports is easy. Metadata on an export is really just a dictionary of labels and values. We know this particular export has one label ("Region") and that it is the enum of the region type. Therefore, once we find or create our export definition, we go ahead and add the export with the region itself (a content control, items control, or other container) and meta data for that region (in this case, the "Region" tag and the enumeration value).

Now we just need to be prepared to supply the exports when our custom provider is queried. This is the GetExportsCore. Fortunately, we get it easy. Instead of having to keep track of all of the rules, the import definition comes with a IsConstraintSatisfiedBy method that calls the Constraint provided to filter the export values. We simply find the definition that matches the contract and the constraint, then provide all of the exports we have. These will then have their meta data parsed and if a capabilities interface is provided, it will be populated with the values so that the Lazy<Type,ITypeCapabilities> target can be populated. Notice I added some debug lines to help troubleshoot.

Now I can tag my export the way I wanted to:

...
<ContentControl mef:RegionExportProvider.Region="MainRegion" .../>
...

There is only one more step I need to take in order for this all to work. Remember back when I showed you how to override the container so we could continue to compose new DeploymentCatalogs into an AggregateCatalog as they became available? When we create that special container, we need to add our secret sauce. We do it like this:

...
var container = new CompositionContainer(catalogService.GetCatalog(), RegionExportProvider.GetRegionExportProvider());
...

Now we've told the container to query our own custom export provider when trying to satisfy parts.

If you recall from my prior posts, I used a routing class to map view types to regions, and loaded the regions like this:

[ImportMany(AllowRecomposition = true)]
public Lazy<FrameworkElement, ITargetRegionCapabilities>[] RegionImports { get; set; }

Our new provider kindly exports the tagged regions, which are then imported with the routing class and used to swap views in and out of the display.

Jeremy Likness

This is a video tutorial to introduce beginners to how to use both MVVM (Model-View-ViewModel) and MEF (Managed Extensibility Framework) with Silverlight (should work for versions 3 and 4). Of course, some "veterans" may want to watch as well in case you've missed some of the fundamentals, or have a clever way to do something that you can share in the comments for future visitors to the page.

In this edition, I build a simple application that allows the user to check a preference on the screen (whether they prefer squares over circles) and then displays a square or a circle. We use MVVM and wire everything together with MEF.

Download the source code: MEFMVVMDemoSln.zip

Click here to watch the video directly if it doesn't appear in the frame below (recommended to watch in full screen): Watch the video in a separate window

Here is the final application:

Download the source code: MEFMVVMDemoSln.zip

Jeremy Likness

Recently I've been having lots of conversations about the Managed Extensibility Framework (MEF), the Composite Application Library (CAL or PRISM), and how they relate. One point of confusion that many people has comes when they try to force the two solutions to work together. In a recent conversation, I mentioned that PRISM has some great features, but that if you are only using it for dynamic module loading and view management, MEF should do fine. Then I promised to post a blog with a reference project ... and here it is.

Download the source for this project

First, let me share that I love PRISM and have been working with it in almost all of my projects for the past year. My Wintellect colleague Rik Robinson has an excellent article on PRISM you can read here. You can also scan this blog with the PRISM tag. However, I've started to really enjoy working with MEF and believe it is quickly becoming the solution of choice for composite Silverlight applications ... especially with it's inclusion in the upcoming 4.0 release. In these 2 posts I'll show you how to tackle dynamic module loading and region management using exclusively MEF instead of PRISM.

I'm working with the preview 9 of the bits and showing what can be done in the current production release of Silverlight which is version 3. To start with, I simply create a new Silverlight Application. I add a folder called "MEF" and throw the bits in there, which is really two DLLs: System.ComponentModel.Composition and System.ComponentModel.Composition.Initialization. I reference those.

The "Bootstrapper" in MEF

Next I create a new empty user control called Shell.xaml (sound familiar?) that just has a grid and a text block so I know it's there. If you are familiar with PRISM, you are familiar with the concept of the Bootstrapper class to wire everything up. With MEF, we'll do it a little different. First, I go inside the shell and simply decorate it with the "export" attribute:

[Export]
public partial class Shell
{
    public Shell()
    {
        InitializeComponent();
    }
}

Next, I go into my main application class (App.cs) and add a property to import the Shell, like this:

...
[Import]
public Shell RootView { get; set; }
...

Finally, in the application start-up method, instead of newing up a "main page" which no longer exists, I simply ask MEF to satisfy my import of the shell, then assign it to the root visual:

private void Application_Startup(object sender, StartupEventArgs e)
{
    CompositionInitializer.SatisfyImports(this);
    RootVisual = RootView;
}

That's it! When I hit F5 I see the text I placed in the shell, so I know it's being placed in the root visual. We're good to go! I'm going to tackle dynamic loading first, then look at region management. I'll need some buttons to trigger the loading, so we'll want to roll a command behavior. This is one of the nice things that comes with PRISM (the commands), but let's see how easy or difficult it is to roll our own.

Custom Commands

Microsoft Expression Blend provides a set of base triggers and behaviors that make it easy to add new functionality like commanding. If you don't have the full tool, don't despair - these are also included in the free SDK you can download. I'm including a reference to System.Windows.Interactivity.

I want to do a trigger action. A trigger action allows me to act on any event, which I prefer over hard-coding just to a button click.

Before I get ahead of myself, though, let's create our command. While Silverlight 3 doesn't have a built-in command object, it does provide the ICommand interface. I'm going to do a partial implementation. I say "partial" because the interface allows for something to be passed to the command, and I'm simply raising the command and assuming null for the sake of this blog post:

public class CommandAction : ICommand 
{
    private readonly Func<bool> _canExecute;

    private readonly Action _execute; 

    public CommandAction(Action action, Func<bool> canExecute)
    {
        _execute = action;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return _canExecute();
    }

    public void Execute(object parameter)
    {
        _execute();
    }

    public void RaiseCanExecuteChanged()
    {
        EventHandler handler = CanExecuteChanged;
        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }

    public event EventHandler CanExecuteChanged;
}

While I haven't looked at the code in PRISM, I assume this is very close to how they wire the DelegateCommand. We hold a function that determines if the command is enabled, and an action to call when the command is invoked. Whoever creates the CommandAction is responsible for passing those delegates in and raising "can execute changed" when appropriate.

Now I can start to work on the command behavior. Because of my unique command type, I'm just going to allow you to pass the name of the command on the data bound object and will dissect the rest. If you bind a view model with "ActionCommand" then I'll let you wire up it up that way. Because we're using MEF to bind our view models, my behavior will get wired well before the bindings happen. I'll need to know when the data context changes, so I build a data context helper. It basically uses dependency properties to listen to a "dummy" binding for changes, then calls an action when the changes happen. It looks like this and is loosely based on a previous post I made on data context changed events:

public static class DataContextChangedHandler
{
    private const string INTERNAL_CONTEXT = "InternalDataContext";
    private const string CONTEXT_CHANGED = "DataContextChanged";

    public static readonly DependencyProperty InternalDataContextProperty =
        DependencyProperty.Register(INTERNAL_CONTEXT,
                                    typeof(Object),
                                    typeof(FrameworkElement),
                                    new PropertyMetadata(_DataContextChanged));

    public static readonly DependencyProperty DataContextChangedProperty =
        DependencyProperty.Register(CONTEXT_CHANGED,
                                    typeof(Action<Control>),
                                    typeof(FrameworkElement),
                                    null);

    
    private static void _DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        var control = (Control)sender;
        var handler = (Action<Control>) control.GetValue(DataContextChangedProperty);
        if (handler != null)
        {
            handler(control); 
        }
    }

    public static void Bind(Control control, Action<Control> dataContextChanged)
    {
        control.SetBinding(InternalDataContextProperty, new Binding());
        control.SetValue(DataContextChangedProperty, dataContextChanged); 
    }
}

In this case, I'm scoping specifically to a control, which is where I believe the lowest level of "is enabled" gets implemented for controls that can react to changes, so that makes sense for our behavior. When I call bind, I pass it a control and a delegate to call when that control's data context changes. Now we can build in our behavior:

public class CommandBehavior : TriggerAction<Control>
{
    public static readonly DependencyProperty CommandBindingProperty = DependencyProperty.Register(
        "CommandBinding",
        typeof(string),
        typeof(CommandBehavior),
        null);

    public string CommandBinding
    {
        get { return (string)GetValue(CommandBindingProperty); }
        set { SetValue(CommandBindingProperty, value); }
    }

    private CommandAction _action; 

    protected override void OnAttached()
    {
        DataContextChangedHandler.Bind(AssociatedObject, obj=>_ProcessCommand());
    }

    private void _ProcessCommand()
    {
        if (AssociatedObject != null)
        {

            var dataContext = AssociatedObject.DataContext;

            if (dataContext != null)
            {
                var property = dataContext.GetType().GetProperty(CommandBinding);
                if (property != null)
                {
                    var value = property.GetValue(dataContext, null);
                    if (value != null && value is CommandAction)
                    {
                        _action = value as CommandAction;
                        AssociatedObject.IsEnabled = _action.CanExecute(null);
                        _action.CanExecuteChanged += (o, e) => AssociatedObject.IsEnabled = _action.CanExecute(null);

                    }
                }
            }
        }
    }

    protected override void Invoke(object parameter)
    {
        if (_action != null && _action.CanExecute(null))
        {
            _action.Execute(null);
        }
    }      
}

OK, let's step through it. I'm using the System.Windows.Interactivity namespace to define a trigger action, which can be bound to any event. I'm scoping it to a control. When my behavior is attached, I'm binding to the data context changed event. I ask it to call my method to process the command when the data context changes (presumably to bind our command). When that fires, I grab the property that is named in my behavior from the data context, cast it to a command, and wire it up to automatically change whether the host control is enabled based on the CanExecute method of the control. When my behavior is invoked, I check this again and then execute.

ViewModel Glue

There's been a lot of discussion (including in this blog) around how to glue the view model to the view. I personally like to keep it simple and straightforward. Here's a view model stubbed out for the shell that lets me click a button to dynamically load a view. I want to disable the button once clicked so they don't load the view more than once.

[Export]
public class ShellViewModel
{
    public ShellViewModel()
    {
        ViewEnabled = true;
        ViewClick = new CommandAction(_ViewRequested,
                                      () => ViewEnabled);
    }

    private bool _viewEnabled;

    public bool ViewEnabled
    {
        get { return _viewEnabled; }
        set
        {
            _viewEnabled = value;
            
            if (ViewClick != null)
            {
                ViewClick.RaiseCanExecuteChanged();
            }
        }
    }

    public CommandAction ViewClick { get; set; }

    private void _ViewRequested()
    {
        ViewEnabled = false;
    }
}

Note I use a property to determine if the command is enabled, then call a method to process it when fired. We'll add more to that method in a minute. Let's get this into our shell. Because the shell is wired up in the application through the initializer, there is no need to initialize or compose again. This is done recursively. So, let me add a little bit to my shell:

<UserControl x:Class="RegionsWithMEF.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    xmlns:command="clr-namespace:RegionsWithMEF.Common.Command;assembly=RegionsWithMEF.Common"
    >
    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Text="Main MEF Shell"/>
        <Button Content="Load Dynamic View into Region" Width="Auto" Height="Auto" Grid.Row="1">
            <interactivity:Interaction.Triggers>
                <interactivity:EventTrigger EventName="Click">
                    <command:CommandBehavior CommandBinding="ViewClick"/>
                </interactivity:EventTrigger>
            </interactivity:Interaction.Triggers>
        </Button>
    </Grid>
</UserControl>

Notice how I use the interactivity namespace to define a trigger for the button. The trigger is for the "click" event, but the way we built the behavior, it can easily fire based on other events as well. I bring in my command behavior, and point it to the "ViewClick" property on my view model. A more advanced implementation would turn that into a full blown binding property and allow binding syntax but for now we'll stick with the simple property name.

In the code behind, I wire in my view model:

[Import]
public ShellViewModel ViewModel
{
    get { return LayoutRoot.DataContext as ShellViewModel; }
    set { LayoutRoot.DataContext = value; }
}

That's it! I run the project to test it, and get a nice text block with a button. When I click the button, it disables immediately. Now let's tackle that dynamic view!

Controlling the Catalog and Container

We want to dynamically load some modules, but first we'll need to tweak our container. By default, MEF is going to create a container in our main application and compose parts to it. Unfortunately, that means when we load other modules/xap files, they won't have access to the container! We need to fix this.

First, I'll create a service to expose an AggregateCatalog that I can add other catalogs to. I want to get the catalog and add parts to it:

public interface ICatalogService
{
    void Add(ComposablePartCatalog catalog);

    AggregateCatalog GetCatalog();

}

Next, I will implement this by creating an aggregate catalog. I'm going to assume when the service is created that we want to include the currently loaded assemblies. This assumption may be wrong and down the road we might inject the catalog, but for now we'll iterate the current deployment (set of running assemblies) and pull them in to parse into our catalog:

public class CatalogService : ICatalogService
{
    private read-only AggregateCatalog _catalog = new AggregateCatalog();

    public CatalogService()
    {
        foreach (AssemblyPart ap in Deployment.Current.Parts)
        {
            StreamResourceInfo sri = Application.GetResourceStream(new Uri(ap.Source, UriKind.Relative));

            if (sri != null)
            {
                Assembly assembly = ap.Load(sri.Stream);
                _catalog.Catalogs.Add(new AssemblyCatalog(assembly));
            }
        }
    }    

    public void Add(ComposablePartCatalog catalog)
    {
        _catalog.Catalogs.Add(catalog);
    }

    public AggregateCatalog GetCatalog()
    {
        return _catalog; 
    }
}

Now we just need to tweak the main application. We'll instantiate the service, then tell it how to expose itself (sounds weird, I know, but when I bring in a module, I want it to be able to add itself to the aggregate catalog, so the catalog service must be exported). We'll let MEF know we want to use this specific container moving forward, and then we'll initialize as before. The new method looks like this:

private void Application_Startup(object sender, StartupEventArgs e)
{
    ICatalogService service = new CatalogService();
    var container = new CompositionContainer(service.GetCatalog());
    container.ComposeExportedValue(service);
    CompositionHost.Initialize(container); 
    CompositionInitializer.SatisfyImports(this);
    RootVisual = RootView;
}

Dynamic Loading of Modules

MEF Preview 9 comes with a deployment catalog that gives us what we need. First, I want to hide the implementation details of loading a view. I'll create an enumeration of views that are available (in this case, only one) and an interface to call when I'm ready to navigate to a view.

For now, I want to just grab the view and verify it's loaded. Then we'll wrap up for today and tackle the region management in the next post.

I extended my shell view model to anticipate two views. In fact, to make the example more interesting, I will load the second view into the first view. Therefore, the second button is only enabled once the first button has been clicked, like this:

SecondViewClick = new CommandAction(
    _SecondViewRequested,
    () => !ViewEnabled && SecondViewEnabled);

Here's our views:

public enum ViewType
{
    MainView,
    SecondView
}

And the interface for our view navigation:

public interface INavigation
{
    void NavigateToView(ViewType view);
}

So now I can go back to my view model and wire in the navigation, as well as make the call. Here is the modified code:

[Import]
public INavigation Navigation { get; set; }

private void _ViewRequested()
{
    ViewEnabled = false;
    Navigation.NavigateToView(ViewType.MainView);
}

private void _SecondViewRequested()
{
    SecondViewEnabled = false;
    Navigation.NavigateToView(ViewType.SecondView);
}

Now I will add my modules. As I mentioned, I just want them to load for now. I can deal with the views later. So I create two more Silverlight applications in my solution called "DynamicModule" and then "SecondDynamicModule.cs" ... yes, the second is a typo because I thought I was adding a class, and was too lazy to re-factor it. So there. I imagine when I load a module I'll want it to do perform some "introductory" functions, so let's define an initialization interface:

public interface IModuleInitializer
{
    void InitModule();
}

In both of my dynamic modules, I add a class that implements this interface and export it. I gave them different names to show it's the interface the matters, but here's what one looks like (right now I just return, but I can set the breakpoint there to test when and if the module is loaded and called):

[Export(typeof(IModuleInitializer))]
public class ModuleInitializer : IModuleInitializer
{
    public void InitModule()
    {
        return; 
    }              
}

OK, now I can implement my INavigation interface. We're going to do two things. First, we'll map views to modules so we can dynamically load them using the DeploymentCatalog. Second, we'll import a collection of module initializers. This is the super-cool feature of MEF: recomposition. When we load the module and put it in our main catalog, it will recompose. This should fire a change to our collection of initializers. We can take the new items and call them, and we'll be initialized. Here's what it looks like:

[Export(typeof(INavigation))]
public class ViewNavigator : INavigation 
{        
    [Import]
    public ICatalogService CatalogService { get; set; }

    [ImportMany(AllowRecomposition = true)]
    public ObservableCollection<IModuleInitializer> Initializers { get; set; }

  private readonly List<IModuleInitializer> _modules = new List<IModuleInitializer>();

    private readonly Dictionary<ViewType, string> _viewMap =
        new Dictionary<ViewType, string>
            {
                { ViewType.MainView, "DynamicModule.xap" },
                { ViewType.SecondView, "SecondDynamicModule.cs.xap" }
            };   

    private readonly List<string> _downloadedModules = new List<string>();

    public ViewNavigator()
    {
        Initializers = new ObservableCollection<IModuleInitializer>();
        Initializers.CollectionChanged += Initializers_CollectionChanged;
    }
    
    void Initializers_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach(var item in e.NewItems)
            {
                var initializer = item as IModuleInitializer; 
                if (initializer != null)
                {
                    if (!_modules.Contains(initializer))
                    {
                        initializer.InitModule();
                        _modules.Add(initializer);
                    }
                }
            }
        }
    }                                                                                              
  
    public void NavigateToView(ViewType view)
    {
        if (!_downloadedModules.Contains(_viewMap[view]))
        {
            var catalog = new DeploymentCatalog(_viewMap[view]);
            CatalogService.Add(catalog);
            catalog.DownloadAsync();
            _downloadedModules.Add(_viewMap[view]);
        }
    }               
}

Right now the navigate to view isn't very flexible. It loads the catalogs but doesn't do anything with the views. I'm also not handling errors when the XAP isn't loaded. We are tracking modules and xaps that were already loaded, so we don't load them again or re-initialize the module. We'll get to that in the next installment when we wire in regions. For now, we can put a breakpoint in the "return" of the init modules, fire up the application, and click our buttons to watch them get dynamically loaded into the system (you can use Fiddler to watch the packets come over the wire). Pretty exciting!

In the next installment, I'll show you how MEF will handle region management.

Download the source for this project

Jeremy Likness

PRISM, also known as Composite WPF, has established itself as a very popular framework for building modular, scalable Silverlight applications. A newer contender, the Managed Extensibility Framework (MEF), has also grown in popularity. In fact, these two frameworks have left people scratching their heads wondering which one to use, when, how, and why.

Download the source code for this project.

Special note: the source won't run "as is." You need to take two steps: first, right click the PRISMMEF.Web project and choose, "set as start project." Second, right click the PRISMMEFTestPage.aspx and choose "set as start page." Then the project will run fine.

MEF will be packaged with Silverlight 4, and indeed has several preview releases available that will work on Silverlight 3 and 4. PRISM is coming out with newer releases that embrace the MEF framework. In fact, both frameworks work well together and know how to talk to each other's containers.

In this series of posts I want to explore some concepts and aspects of solving the Silverlight application problem using both PRISM and MEF. I will use PRISM primarily for its ability to integrate views into regions, to dynamically load modules, and to provide an abstract messaging contract with the event aggregator. MEF will be used for extensibility and to really tap into the ability to go out, find exports, and glue them into imports.

My primary goal in this short series will be to establish patterns for binding the view model to the view, and to dynamically load views and modules. We'll look at how to do this in the current version of Silverlight 3. It's important to note that future MEF releases may address some of the issues I tackle here and will make some workarounds obsolete, so stay tuned with that. I also want to express my sincere gratitude to Glenn Block (or, if you prefer, @gblock), a key member of the MEF team (and former member of the PRISM team, I believe, as well) for helping me with some of these examples and providing invaluable insights related to the inner workings of MEF.

Today we're going to leave MEF to the side and focus on what PRISM and the IoC container that comes with it, Unity, provide. The challenge is something I see discussed quite often, and that is how to meld the view model and the view together. Some people seem to abhor using code-behind at all, so I want to tackle a few solutions to this while also providing my own pragmatic way that, ahem, does use a little bit of code behind (and explain why I really don't care).

So, let's get started. We're going to have three main views today. The first will be the outer shell, which binds to a message and a button to dynamically load a second module. The module will have a second view that, in turn, will activate a third view. I am also going to show you three ways to bind your view model to your view using Unity. I will use view models with depedencies because these are the ones that cannot be referenced directly in XAML because the XAML parser doesn't implicitly know how to resolve dependencies.

The pattern for establishing a PRISM project is fairly well-established by now. We create a new Silverlight Application, blow away the default user control provided, then make a shell and a bootstrapper class that inherits from UnityBootstrapper.

I'll also add a class project called "common" to hold interfaces, base clases, and other services or parts that are used by the entire application.

In common, we'll define our service behavior. This could be wired to a "real" service but for now is just a mock one to demonstrate how these various methods work. The service contract looks like this:

public interface IService
{
   void GetStuff(Action<List<string>> action);

   void GetMoreStuff(Action<List<string>> action); 
}

I'm using the method outlined in Simplifying Asynchronous Calls in Silverlight Using Action. We call the service, and send it a method to call back on us with the returned value. In this case, it is just two different lists of strings.

I created a separate project "service" to implement the interface. The code is simple, and is also the first place I use a little MEF. I'm simply exporting the service so that if I want to use MEF to import it, I can. Today we'll let Unity wire it up and I'll show you how.

The service implementation is straightforward. Again, we'll add some MEF so it's ready when we look into it. In this case, instead of calling a "real" service, I just hit the callback with a pre-determined list of numbers that most will recognize. The second method does the same, only in Spanish. The class looks like this:

[Export(typeof(IService))]
public class Service : IService
{
    public void GetStuff(Action<List<string>> action)
    {
        action(new List<string> { "One", "One", "Two", "Three", "Five", "Eight", "Thirteen" });
    }

   public void GetMoreStuff(Action<List<string>> action)
    {
        action(new List<string> { "Uno", "Uno", "Dos", "Tres", "Cinco", "Ocho", "Trece" }); 
    }

    #endregion
}

Method 1: Provider

So now we can work on our view models. The main shell simply shows a title and exposes a button to click to dynamically load another module. The model looks like this:

public class ShellViewModel 
{
    const string APPLICATION = "This is the PRISM/MEF project demonstration.";

   public ShellViewModel(IModuleManager moduleManager) 
    {
        ModuleCommand = new DelegateCommand<object>(o =>
        {
            moduleManager.LoadModule("Module");
        });           
    }

    public ShellViewModel()
    {            
    }

    public string Title
    {
        get { return APPLICATION; }
    }

    public DelegateCommand<object> ModuleCommand { get; set; }    
}

Our problem with instantiating this in XAML is that the XAML parser doesn't understand how to resolve the dependency for IModuleManager. This is needed because I am going to dynamically load another module when you click the button bound to the ModuleCommand. As I mentioned, there are several ways to make the glue and one way is to use a provider.

The provider is a base class which has only two purposes. First, it is typed to a class so that multiple view models will generate multiple type instances. We need this so we can have different ways to resolve our classes. Second, it exposes a mechanism to resolve our models. In this way, I'm not tightly coupled to Unity. I recognize that there has to be some external force supplying me with the object to resolve dependencies, but I'll hold off on understanding just what that is.

This leaves me with something like this:

public abstract class ViewModelProviderBase<T> : INotifyPropertyChanged where T: class
{
    public static Func<T> Resolve { get; set; }

    public ViewModelProviderBase()
    {
        T viewModel = Resolve();
        if (viewModel != null)
        {
            _viewModel = viewModel; 
        }
    }

    private T _viewModel;

    public T ViewModel
    {
        get { return _viewModel; }
        set
        {
            _viewModel = value;
            OnPropertyChanged("ViewModel");
        }
    }        

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName)); 
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

So what we have is a base class typed to something. It exposes a static method to resolve that something. This is why the generic type works, so we have one method for resolution per type. It holds a reference to "whatever" and exposes it in the ViewModel property, all the while playing nice with the property changed notifications to update any bindings. What does this buy us?

Now, to resolve my main view model, I can create a provider like this:

public class ShellViewModelProvider : ViewModelProviderBase<ShellViewModel>
{        
}

Fairly straightforward, now we have a typed instance. In my bootstrapper or somewhere that "knows" what I've chosen to manage my objects, I can assign the resolver function like this:

ShellViewModelProvider.Resolve = Container.Resolve<ShellViewModel>;

Now the provider knows how to ask for a new instance of the type, with all dependencies sorted out. Then, in the XAML, we can simply bind the view model with no code behind by pointing to the provider, like this:

<UserControl.Resources>
   <vm:ShellViewModelProvider x:Key="ViewModelProvider"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource ViewModelProvider},Path=ViewModel}">

The resource creates a new instance of the provider. This calls to our resolver (in this case, the Unity container) and returns the view model, then binds it through the exposed ViewModel property.

We've achieved a binding without code behind, but it feels a little "artificial." While there wasn't code behind, we did have to do some extra work up front to glue the resolver to the type. Let's try something a little more natural in our dynamic module.

Method 2: View Injection

To me, this method feels like it makes the most sense. It is able to facilitate giving me objects and resolving dependency trees without the classes really knowing "how" it's done. In the last example, we had a base provider that was a sort of liason and had knowledge of the model and the way the model is resolved. With constructor injection, you simply have a class and are given your concrete instances. You program to the interface, and don't worry about how those interfaces were resolved. It's the pure essence of a Unity pattern where the bootstrapper wires it up, then starts making objects and injecting what they need.

To make our dynamically loaded module, we add a new project as a Silverlight Application (this is important, it's added as an application, not as a class library). I called this just "Module." I can add all of the references that the parent project has, then right click and set "copy local" to false. The references will be there when the module is loaded, so doing this lets you code to the references without having a bloated XAP file. Most of the modular XAPs with dynamic PRISM are a few kilobytes as opposed to the 100K+ "main" XAPs that get generated due to this layering and reuse.

Set up a module catalog by adding a type of "Silverlight Resource Dictionary" which generates a XAML file with no code behind and a content type of "page." You can change this to extend to the PRISM module namespace and declare your modules, like this (mine is in a subfolder called Modules, and I called the file ModuleCatalog.xaml).

<m:ModuleCatalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:sys="clr-namespace:System;assembly=mscorlib"
                 xmlns:m="clr-namespace:Microsoft.Practices.Composite.Modularity;assembly=Microsoft.Practices.Composite">
    <m:ModuleInfoGroup Ref="PRISMMEF.Module.xap" InitializationMode="OnDemand">
        <m:ModuleInfo ModuleName="Module"
                      ModuleType="PRISMMEF.Module.ModuleInit, PRISMMEF.Module, Version=1.0.0.0"/>
    </m:ModuleInfoGroup>   
</m:ModuleCatalog>

Here, I'm giving the module all it needs: a name, the XAP it will load from, and how the assembly and types marry in. PRISM wants the type of the module class to call to initialize everything once the XAP file is loaded. You wire this type of catalog into PRISM by doing this in the bootstrapper:

protected override IModuleCatalog GetModuleCatalog()
{
   return ModuleCatalog.CreateFromXaml(
       new Uri("PRISMMEF;component/Modules/ModuleCatalog.xaml", UriKind.Relative));
}

If you don't remember, in the main view model we took in a reference to the module manager and wired a command to do this: moduleManager.LoadModule("Module");. This causes the module manager to look up in the catalog, find the entry, note that it is not yet loaded, then pull in and parse the XAP. This is the dynamic loading.

Let's hop over to the dynamically loaded module. This module is going to use the service and bind a list of controls to the first method (the one that returns numbers in English). The view model looks like this:

public class StuffViewModel : INotifyPropertyChanged
{
    public StuffViewModel(IService service)
    {
        ListOfStuff = new ObservableCollection<string>();
        service.GetStuff(stuff =>
            {
                foreach (string thing in stuff)
                {
                    ListOfStuff.Add(thing);
                }
            });       
    }

    private DelegateCommand<object> _dynamicViewCommand;

    public DelegateCommand<object> DynamicViewCommand
    {
        get { return _dynamicViewCommand; }
        set
        {
            _dynamicViewCommand = value;
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs("DynamicViewCommand"));
            }
        }
    }
 
   public ObservableCollection<string> ListOfStuff { get; set; }


    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

A few things to notice here. First, there is a dependency on the service and when constructed, it will immediately call to the service to get the list of strings. Second, we have a command to dynamically load view (in this case, the view is loaded with the module, so a better term would be dynamically display the view), but we leave the resolution or implementation of the command up to external forces to decide.

Back in our Bootstrapper class, I need to tell Unity how to resolve the service. I override ConfigureContainer and give it this code:

protected override void ConfigureContainer()
{
    base.ConfigureContainer();
    Container.RegisterType&type;IService, Service.Service>();                                                                  
}     

Now Unity knows that when I ask for IService, I want Service.

In my new module, everything is set up in the ModuleInit. This is the type referenced in the catalog, and also implements IModule. We're going to to do two key things here. First, we'll take in a region manager and register the main view for this module. Second, we're going to tell Unity how to give us the view we'll show dynamically when we ask for it. This happens here:

public class ModuleInit : IModule
{
    IRegionManager _regionManager;
                    
    public ModuleInit(IUnityContainer container, IRegionManager regionManager)
    {
        container.RegisterType<UserControl, DynamicView>("DynamicView"); 
        _regionManager = regionManager;          
    }

    #region IModule Members

    public void Initialize()
    {            
        _regionManager.RegisterViewWithRegion("MainRegion", typeof(StuffView));
    }

    #endregion
}

Don't worry about the DynamicView control just let. We set up Unity to say, "If I want a UserControl, labeled DynamicView, give me the DynamicView type." We could just as easily made the label "foo" and provided the type "bar". The module initializer is a great place to configure the parts of the container specific to that module. The StuffView is what is displayed.

You've seen the view model, so let's talk about the view. The XAML looks like this:

<Grid x:Name="LayoutRoot" Background="White">   
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ListBox ItemsSource="{Binding ListOfStuff}"/>
        <Button Grid.Column="1"
                Content="Add View"
                cal:Click.Command="{Binding DynamicViewCommand}"/>
    </Grid>

Two columns, one for the list of stuff, and the other a button to show the next view.

How do we glue our view model? As I mentioned, this does involve code behind but makes the most sense to me. We take advantage of the way Unity resolves dependencies and code our view like this:

public partial class StuffView : UserControl
{            
    public StuffView()
    {
        InitializeComponent();          
    }

    public StuffView(StuffViewModel viewModel, IUnityContainer container) : this()
    {
        LayoutRoot.DataContext = viewModel;
        viewModel.DynamicViewCommand = new DelegateCommand<object>(o =>
        {
            container.Resolve<IRegionManager>().RegisterViewWithRegion("MainRegion",
                () => container.Resolve<UserControl>("DynamicView")); 
        });
    }      
}

We could do this with properties and attribute them with the Dependency attribute as well. In this case, we reference the view model so it is wired in by Unity with any dependencies. Because we get the container, we're also able to resolve the IRegionManager and tell it to add the dynamic view to the region when the command is executed. Notice that here we are resolving UserControl, which we set up in the module initialization function. The important part is that my view doesn't have to understand how a region manager does what it does or know what the other view is, it simply calls the contract and passes along what the container resolves for us.

Of course, that command is not going to do much unless we have the actual view.

The dynamic view will share the same view model and show the same list for the sake of simplicity, but I wanted to show another way of wiring the view model to the view.

Method 3: Behaviors

Again, our challenge is that XAML doesn't know how to resolve dependencies. So, we can use constructors or decorated properties and let Unity wire them in, or create our own constructs that have to be notified about what to do and then supply the needed classes.

This method uses an attached property to create the view model and attach it to the view. This time instead of keeping it overly generic, I went ahead and referenced the unity container. The behavior needs to be wired up with the container so it can resolve view models, but the view model type is passed dynamically.

The behavior looks like this:

public static class ViewModelBehavior
{
    // this is the part I like the least, could abstract it
    // but this example is long enough already!
    public static IUnityContainer Container { get; set; }

    public static DependencyProperty ViewModelProperty = DependencyProperty.RegisterAttached(
        "ViewModel",
        typeof(string),
        typeof(ViewModelBehavior),
        new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnModelAttached)));

    public static string GetViewModel(DependencyObject obj)
    {
        return obj.GetValue(ViewModelProperty).ToString();
    }

    public static void SetViewModel(DependencyObject obj, string value)
    {
        obj.SetValue(ViewModelProperty, value);
    }

    public static void OnModelAttached(object sender, DependencyPropertyChangedEventArgs args)
    {
        FrameworkElement element = sender as FrameworkElement;

        if (element != null)
        {
            if (args.NewValue is string)
            {
                string viewModelContract = args.NewValue.ToString();
                if (!string.IsNullOrEmpty(viewModelContract))
                {
                    Type type = Type.GetType(viewModelContract);
                    element.DataContext = Container.Resolve(type); 
                }
            }
        }
    }
}

So what's interesting here is that we have a reference to the unity container, and what happens when the property is attached. It is expecting a fully qualified type passed in a string. We use the Type class to resolve the type, then use the containe to resolve the instance and bind it to the data context of the element that had the behavior attached.

This leaves our code-behind clean:

public partial class DynamicView : UserControl
{
    public DynamicView()
    {
        InitializeComponent();
    }
}

And gives us flexibility to use the behavior to wire in whatever we want in the XAML:

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <TextBlock Text="This list was bound using the behavior."/>
    <ListBox 
        Grid.Row="1" 
        vm:ViewModelBehavior.ViewModel="PRISMMEF.Module.ViewModel.StuffViewModel, PRISMMEF.Module, Version=1.0.0.0" 
        ItemsSource="{Binding ListOfStuff}"/>


Notice the fully qualified view model type on the ListBox, which uses the behavior to resolve and then bind the view model. Wrapping Up

What we can do now is show a view with a button that was bound with no code behind and let Unity wire in dependencies. Clicking the button dynamically loads a new module that takes in a service reference, calls the service, and shows items returned from the service. This is wired in and bound in the code behind and uses constructor injection. This new view then displays the list next to a button that adds another view, bound to the same list.

All of these scenarios require a bit of work to get where we need to go. Will MEF give us something better? Perhaps. Next post, I will explore why out of the box in Silverlight 3 we can't simply glue pieces together using MEF without digging into the internals and providing some infrastructure. Much of that infrastructure will be out of the box in future versons, but this will help us understand what is going on behind the scenes. We will set up the infrastructure in anticipation of using MEF, then the third and final installment will involve another dynamically loaded module that wires it all together using MEF with a little help from Unity.

Stay tuned!

Download the source code for this project.

Special note: the source won't run "as is." You need to take two steps: first, right click the PRISMMEF.Web project and choose, "set as start project." Second, right click the PRISMMEFTestPage.aspx and choose "set as start page." Then the project will run fine.

Jeremy Likness

I've been enjoying learning more about the Managed Extensibility Framework (MEF) and exploring various ways to integrate it with applications. After toying with MEF on Silverlight for awhile, I began to wonder about using it to export/import UI pieces or even define data elements in XAML. After a tweet to @gblock confirmed there was not native support, I set out to see what I could do. (If you're not familiar with MEF, take a look at my 10 minute walkthrough.)

The result is by no means ideal and is certainly a contrived "proof of concept" solution, but I believe it will help expose some of the custom extension points available with MEF and just how flexible it truly can be.

Download the Source

My goal was to minimize code behind for a common scenario of having pages with groups of widgets. Widgets will most likely be defined as user controls, but we've already seen plenty of examples there. I wanted to be able to define them as resources in pure XAML, no code behind, then import them into something like a StackPanel as child elements.

The Attachable View Model

The first thing I created was an attachable view model. It would get a list of FrameworkElement for binding to a control. To make it even more interesting, I wired in an attached property. This way I can simply attach the view model to a control and it will automatically pull in the parts and populate the children.

The initial shell looked like this:


public class ViewModel
{
    private static List<FrameworkElement> _uiParts = new List();
    
    [ImportMany("UIPart", AllowRecomposition = true)]
    public List<FrameworkElement> UIParts
    {
        get { return ViewModel._uiParts; }
        set { ViewModel._uiParts = value; }
    }

    public ViewModel()
    {
        var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
        var container = new CompositionContainer(catalog);
        container.ComposeParts(this);
    }

    static ViewModel()
    {
        new ViewModel();
    }

    public static readonly DependencyProperty ViewBinderProperty = DependencyProperty.RegisterAttached(
        "ViewBinder", typeof(bool), typeof(ViewModel), new PropertyMetadata(new PropertyChangedCallback(OnViewBound)));

    public static void OnViewBound(object sender, DependencyPropertyChangedEventArgs args)
    {
        // make sure we want this ...
        if (args.NewValue != null && args.NewValue.GetType().Equals(typeof(bool)) && (bool)args.NewValue)
        {
            Panel panel = sender as Panel;
            if (panel != null)
            {
                // iterate the parts
                foreach (FrameworkElement element in _uiParts)
                {
                    // clone it
                    FrameworkElement newElement = Clone(element);
                    
                    // give it a unique name
                    newElement.SetValue(FrameworkElement.NameProperty, Guid.NewGuid().ToString());
                    
                    // inject it
                    panel.Children.Add(Clone(newElement));
                }
            }
        }
    }

    public static bool GetViewBinder(DependencyObject obj)
    {
        return (bool)obj.GetValue(ViewBinderProperty);
    }

    public static void SetViewBinder(DependencyObject obj, bool value)
    {
        obj.SetValue(ViewBinderProperty, value);
    }
}

So far it feels pretty much like a standard class hosting a dependency property. You'll notice it's a bit strange, however, as the class itself is not static. This is because MEF is expecting an instance to compose the parts in. To facilitate that, I have an instance constructor that follows the general MEF pattern ... throw the catalog into the container and compose the parts. The "instance" getter and setter is really a facade that populates the static list of parts, in this case I'm just asking for any type of FrameworkElement. Obviously, those will have to come from somewhere else.

Because my intention is to use a resource dictionary, I must be able to share the elements. Silverlight won't let you take an element that is already the child of another element and then move it somewhere else. I have to assume I may reuse some of these elements as well (for example, this could be extended with a filter to choose the types of elements). So, instead of adding the elements directly to the parent, I am cloning them.

Thanks here goes to Justin Angel for his very functional clone method that I found here. I left it out of the code snippet above to keep it simple, but it is included in the source.

Now we need to tackle the task of exporting the framework elements. Ideally, I just want to put them into a resource dictionary, tag them somehow, and have the magic work. Fortunately, MEF gives us a nice ExportProvider we can derive from to do just that. There's an excellent article I started with by the "Code Junkie" you can access here.

It may have made more sense to split out the dependency properties and the provider to separate classes, but I figured, why not? So here is a custom export provider that also hosts some attached properties to facilitate exporting XAML:


public class XAMLProvider : ExportProvider
{
    private static readonly Dictionary<ExportDefinition, List<Export>> _exports = new Dictionary<ExportDefinition, List<Export>>();

    private static readonly XAMLProvider _provider = new XAMLProvider();

    public static DependencyProperty MEFExportProperty = DependencyProperty.RegisterAttached("MEFExport", typeof(string), typeof(XAMLProvider),
        new PropertyMetadata(new PropertyChangedCallback(OnMEFExport)));

    public static void OnMEFExport(object sender, DependencyPropertyChangedEventArgs args)
    {
        if (args.NewValue != null && !string.IsNullOrEmpty(args.NewValue.ToString()))
        {
            string contract = args.NewValue.ToString();
            _provider.AddExport(contract, sender);
        }
    }

    public static string GetMEFExport(DependencyObject obj)
    {
        return (obj).GetValue(MEFExportProperty).ToString();
    }

    public static void SetMEFExport(DependencyObject obj, string value)
    {
        obj.SetValue(MEFExportProperty, value); 
    }

    private static readonly object _sync = new object();

    public static XAMLProvider GetXAMLExportProvider()
    {
        return _provider;
    }

    public void AddExport(string contractName, object export)
    {
        lock (_sync)
        {
            var found =
                from e in _exports
                where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0
                select e;

            if (found.Count() == 0)
            {
                ExportDefinition definition =
                    new ExportDefinition(contractName, new Dictionary());

                _exports.Add(definition, new List<Export>());
            }

            Export wrapper =
                new Export(contractName, () => export);

            found.First().Value.Add(wrapper);
        }
    }

    protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
    {
        var contractDefinition = definition as ContractBasedImportDefinition;
        IEnumerable<Export> retVal = Enumerable.Empty<Export>();

        if (contractDefinition != null)
        {
            string contractName =
                contractDefinition.ContractName;

            if (!string.IsNullOrEmpty(contractName))
            {
                var exports =
                    from e in _exports
                    where string.Compare(e.Key.ContractName, contractName, StringComparison.OrdinalIgnoreCase) == 0
                    select e.Value;

                if (exports.Count() > 0)
                {
                    retVal = exports.First();
                }
            }
        }

        return retVal; 
    }
}

The only override provided is to actually get the exports for a provided input definition. Everything else is left to us.

The first thing I did was create a dictionary. The key is the contract name (in MEF, the contract name is just a string ... if you use a type or an interface, then the fully qualified name becomes the string for the contract). The value is a list of all exports attached to that contract.

The dependency property allows me to attach "MEFExport" to any XAML object and give it a contract name. When this property is attached, it will look for the name in the dictionary and then either create a new entry or add the element to the existing list. It's as simple as that!

When the GetExportsCore is called, we are given an import definition. For a more complex example, we could look at attributes and other extensions. In this case, I'm simply extracting the contract name, finding the key in the dictionary and then sending off any exports that were loaded with the key.

Now I can add a resource dictionary and tag my elements for export. Mine looks like this:


<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MEFExtension">
    <TextBlock FontSize="32" Text="This is a text block." x:Key="ui1" local:XAMLProvider.MEFExport="UIPart"/>
    <Rectangle Width="100" Height="100" Fill="Red" x:Key="ui2" local:XAMLProvider.MEFExport="UIPart"/>
    <TextBlock FontSize="16" Text="This won't get imported." x:Key="ui3"/>
    <Ellipse HorizontalAlignment="Left" Fill="Blue" Stroke="Black" Width="100" Height="50" x:Key="ui4" local:XAMLProvider.MEFExport="UIPart"/>
</ResourceDictionary> 

I threw in a dummy text block without tagging it to show that it won't get exported because the property is not attached. So now when that resource dictionary is pulled in, we can parse the XAML and export the elements. We need to let MEF know about our custom provider. Going back to my view model, I'll change the container creation to this:


var container = new CompositionContainer(catalog, XAMLProvider.GetXAMLExportProvider());
            

Notice I now passed in our custom export provider.

Now all of the elements are in place. The custom export provider knows how to scan XAML and load up elements for export, we've added a resource dictionary with some elements to export, and the view model is asking for imports and has its own attached property so that we can push the elements to any type of panel.

Last step: I go into my main page, pull in the resource dictionary and bind the view model:


<UserControl x:Class="MEFExtension.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
    xmlns:local="clr-namespace:MEFExtension">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    <StackPanel Orientation="Vertical" Width="Auto" local:ViewModel.ViewBinder="true"/>
</UserControl>

So the resource dictionary will get pulled in. As the keys are processed, it will fire the attached properties and load them into exports. I gave them the "UIPart" contract. When the view model is attached, it will new an instance that fires the composition container for MEF. This will use the custom provider. Because we have the list of elements marked "UIPart", the exports will match and get loaded. The attach event will clone these objects and add them as children to the stack panel.

The result?

Silverlight MEF ExportProvider

There you have it, an example of extending the, ah, Managed Extensibility Framework, to support exporting using attached properties in XAML (I did this in Silverlight 3, so I had to add the reference to the System.ComponentModel.Composition from the download ... it is included in Silverlight 4).

Download the Source

Jeremy Likness

In preparing for an upcoming talk I'll be giving on the Managed Extensibility Framework (MEF), I wanted to demonstrate how fast and easy it is to use in a sample, reference application. This application creates a dynamic plugin. I first link a plugin and show it active, then I create a second plugin and show how it is dynamically added to the program during runtime. It all takes under 10 minutes and would be faster if I didn't want to pace the demo to show the steps involved.

Here is a direct link to the video

Here it is embedded:

Jeremy Likness