Managed Extensibility Framework

Several months ago we formed what we call Application Framework Core team. The charter of the team is to play the same role in the application frameworks space (WinForms, ASP.NET, WPF, Silverlight) as the Base Class Libraries (BCL) team plays at the bottom of the platform stack.

The BCL team did a good job fulfilling the role of the team responsible for decreasing duplication and providing common abstractions for the low levels of the platform. Unfortunately, we did not have a similar team really focused on these sets of issues higher up on the stack. This resulted in some unfortunate duplication (like several data binding models for each of the application models, different dependency property system for WPF and WF) and lack of common abstractions (what undo APIs should my generic application plugin call?) for application model code. The Application Framework Core team is now in place to start addressing the problems.

One of the first concrete projects that we are working on and are ready to slowly talk about is what we call the Managed Extensibility Framework (MEF). We observed that there are more and more places in the .NET Framework itself and increasingly managed applications (like Visual Studio) where we want to provide, or already provide, hooks for 3rd party extensions. Think about TraceListener plugins for the TraceSource APIs, pluggable rules for Visual Studio Code Analysis (and the standalone FxCop), etc. In the absence of a built-in extensibility framework (like MEF), our developers who want to enable such extensions often are forced to create custom mechanisms, thus duplication. We hope that MEF will both stop such duplication and encourage/enable more extensibility in the Framework and applications built on top of it.

We will blog more details about MEF in the upcoming months, but here are some early details (subject to changes, of course): MEF is a set of features referred in the academic community and in the industry as a Naming and Activation Service (returns an object given a “name”), Dependency Injection (DI) framework, and a Structural Type System (duck typing). These technologies (and other like System.AddIn) together are intended to enable the world of what we call Open and Dynamic Applications, i.e. make it easier and cheaper to build extensible applications and extensions.

The work we are doing builds on several existing Microsoft technologies (like the Unity framework) and with feedback from the DI community. The relationship with the Unity team is the regular relationship between the P&P group and the .NET Framework group where we trickle successful technologies and ideas from the P&P team into the .NET Framework after they have passed the test of time. We have done this with some features in the diagnostics, exceptions, and UI space in the past. The direct engagement with the DI community is also starting. We gave a talk on the technology at last week’s MVP Summit, and talked with Jeremy Miller (the owner of Structure Map) and Ayende Rahien (Rhino Mocks) . We got lots of great feedback from Jeremy and Ayende and I think their experience in the DI space and their feedback will be invaluable as the project evolves. Thanks guys! We are of course also looking forward to engaging others in the DI community.

And finally here is some code showing basic scenarios our framework supports:

Creating an Extension Point in an Application:

public class HelloWorld {

  [Import] // import declares what a component needs

  public OutputDevice Output;

   public void SayIt() {

   Output.WriteLine("Hello World");

  }

}

// Extension Contract

public abstract class OutputDevice {

  void WriteLine(string output)

}

1. Creating an Extension

[Export(typeof(OutputDevice))] // export declared what a component gives

public class CustomOutput : OutputDevice {

  public void WriteLine(string output) {

    Console.WriteLine(output);

  }

}

 

2. Magic that makes composes (DIs) the application with the extensions.

var domain = new ComponentDomain();

var hello = new HelloWorld();

// of course this can be implicit

domain.AddComponent(hello);

domain.AddComponent(new CustomOutput());

domain.Bind(); // bind matches the needs to gives

hello.SayIt();

Expecting lots of questions, I will preemptively answer (J): we don’t yet know whether or when we will ship this. We do have working code and we are looking into releasing a preview/CTP of the technology. For now we would be very interested in high level feedback. What do you think hinders extensibility in frameworks and application? Where would you like the Framework to be more extensible? What DI framework features you need, like, want, and use on daily basis? i.e. is constructor injection required?

And lastly, we are hiring! :-)