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! :-)
Comments
Anonymous
April 25, 2008
Looking good - I've been waiting for such a thing to be available in the general framework for a long time :D To answer one of your specific questions, I think constructor injection is very much required, and I explain why here: http://blogs.msdn.com/ploeh/archive/2007/06/02/StateYourDependencyIntent.aspx.Anonymous
April 25, 2008
First of all constructor injection is a must for me also. One thing that I don't like is that I have to clutter my classes with attributes to use your DI container. You should at least have a way to make this optional. My classes shouldn't depend in any way on the DI container used. Take a look at how other DI containers handle this. Also please provide good extensibility points to the DI container itself and make it easy to unit test. If you want to do it right, take a look at how the ASP.NET MVC team has done it. Listen to the community, look at other projects in this domain, ship early and often, make it easy to test, extend or even replace. If you keep this in mind, this could become useful. Thanks.Anonymous
April 25, 2008
Fantastic news. It is important that these extensions can be added and removed/replaced at runtime and also able to run at full performance. The current approach to making extensions unloadable by using separate AppDomains results in too much of a performance-hit if there is a lot to serialize across the AppDomain boundary. I look forward to hearing more about this as you progress.Anonymous
April 25, 2008
I think that constructor injection is absolutely necessary (I use Castle at the moment). If it is not available, I probably would not use MEF. Overall, I am quite disappointed by the default public constructor requirement in a lot of places within framework (why can't all things like JSON serialization just use TypeConverter.CreateInstance). It makes class much less maintainable, since there is not static way to check it got all dependencies.Anonymous
April 26, 2008
Krzysztof, From your prospective, what makes dependency injection better than some of the existing patterns (such as ProviderBase)? How would adding attribute-based dependency injection affect usability of the .NET framework? For example, one could argue that the following example is comparable in flexibility but easier to understand and debug. <code><pre> public class HelloWorld { public void SayIt() { Console.WriteLine("Hello World"); } } // Service Contract public static Console { private static TextWriter _out; public static void WriteLine(string s) { _out.WriteLine(s); } // Injection Point public static void SetOut(TextWriter out) { _out = out; } } // Provider Contract public abstract class TextWriter { public virtual void WriteLine(string s); } // Concrete Provider public class StringWriter : OutputDevice { private StringBuilder _sb; public override void WriteLine(string s) { _sp.Append(s); } } // There is no magic Console.SetOut(new StringWriter()); var hello = new HelloWorld(); hello.SayIt(); </pre></code> Although more verbose, with a simple code generation tool (perhaps based on T4), this example could be as easy to implement as the example with attribute-based dependency injection. What do you think? Thanks.Anonymous
April 26, 2008
The comment has been removedAnonymous
April 27, 2008
I saw Kit's demo at recent MVP summit and was great but, how does this fit with System.AddIn?Anonymous
April 27, 2008
Very interesting post over here.Anonymous
April 27, 2008
Please don't forget code implemented in DLR-based languages, which often can't use attributes, provide constructors or be loaded directly from an assembly. The most generic way to supply an object-creation function is through a delegate.Anonymous
April 27, 2008
I think that Constructor Injection is absolutely required because it allows you to strictly define the object dependencies and abstracts you from a particular DI system. I can therefore write a class that will support DI with CastleWindors, Unity etc. Use of attributes should be a last resort. Also, why reinvent the pattern? IUnityContainer container = new UnityContainer(); container.RegisterType<CustomOutput>(); var hello = container.Resolve<HelloWorld>(); hello.SayIt();Anonymous
April 28, 2008
Here is my wishlist :) Total transparancy is number one for me. I should be able to use existing code with a DI framework, no recompile or change needed. This includes existing .NET framework code. So I would at least need transparent constructor and property injection, and a way to assign factory objects through a delegate/method, specify singleton. transparent also means that it should work with all the different hosts like ASP.NET, ClickOnce, NT Services, etc. Anything else simply won't do. What also needs to be totally transparent is the errors you inevitably make in configuring the DI framework. Nothing worse than going through attributes or xml config to finally find a typo somewhere because the stacktrace gives you too little info. You need proper exception handling with human readable description of the reason why it doesnt work. The configuration should be validatable/checked for errors before running your application to limit this happening, hooking this into compilation of code would be great. Configuration should be possible through XML and programmatic interface. (Configuration should obviously be extensible and replaceable with other implementations) As for programmatic interface I would like two flavours, standard .NET (inside the executing program) and DSL scripting interface (outside of the executing program, comparable to XML configuration) for instance a DLR language or a less verbose CLR language like boo. In my opinion a framework is partly as good as the tools it comes with. The configuration should have an 'editor' of sorts in Visual Studio, (checkout spring ide, its got some nice features on the java side). Even better would be if you could configure and connect the objects you want through some kind of class browser and select your output for configuration. the better you get this part down, the easier it will be to adopt. Other than that I would like lifecycle management, hooks for creation and cleanup, a facility like extension model like Windsor Castle has, custom XML schema extensions like spring and an easy way to provide plugins through DI and the possibility to assign separate Appdomains for the plugins would be great as well.Anonymous
April 28, 2008
This seems very cool, but I have concerns regarding usability. How is it intended to be used in larger projects?Anonymous
April 28, 2008
I don't mind Constructor Injection but I've always preferred Property (Setter) Injection or eve Method Injection but that's because I like to drive the design I make using my interfaces - which makes .ctor injected dependencies 'invisible' to me. Not saying you should ban CI - not at all! I just wanted to voice the opposite opinion in this torrent of praise for this one type of injection. ;~) That's my €0.02.Anonymous
April 28, 2008
We use our own IoC/DI framework. I think standardizing on the (optional) attributes is a good thing. This way other frameworks can use these same attributes. Not sure about the .Bind() idea - binding consumers and providers of services is often much more complicated than the 1:1 relationship that this implies. Also, DI is all about the configuration. What about setting properties using reflection? What about a standard container? or container interface?Anonymous
April 28, 2008
The comment has been removedAnonymous
April 28, 2008
Invent, invent, invent :(
- Why not simple reuse of other framework like Unity / Spring?
- Dont forget about configurable (as opposed to programmable)
- I read it and wansn't amazed, everything was already done by other framework - did i miss anything?
Anonymous
April 28, 2008
The comment has been removedAnonymous
April 28, 2008
Thanks for all the great feedback. It will really help us weigh the pros and cons of the two main design issues: constructor injection and the attribute based programming model. We have had many discussion about these two internally, and there are interesting tradeoff we would need to make to add these two features. I will try to erite about the tradeoffs (or ask somebody on the team to do it) to start a focused discussion about these two. Thanks again for the feedback. It's all great!Anonymous
April 28, 2008
Ran, We want to use it for extensibility of the Framework itself and Visual Studio. We cannot use Unity or Spring for this.Anonymous
April 28, 2008
@Oleg My biggest issue with this is I expect Console.WriteLine to write to the Console, not some other stream (unless the console is being redirected to a file, which is standard behaviour). OutputDevice only implies the input will go to some device. Could be the console, a printer, a network stream, etc... @Krzysztof Performance is critical. I'd also like to see the attributes in a non-specific namespace, so other DI frameworks could use the same metadata. Ideally this would be general enough for any DI and/or IoC framework to consume. In the past, I have had mixed feelings about using attributes within one's code for the DI / IoC framework; however, I now believe it to be necessary. Why? Primarily from a discoverability point of view - I want to be able to use a generic tool to examine an assembly and identify the dependencies. Configuration is great, but it is very difficult to determine the original engineer's intent without the attributes. From your example above, it is easy for me to see (given the presence of the [Import] attribute) that the Output property should be injected / provided externally. Without the attribute (and being purely configuration based) how do I know this? I now have to look elsewhere, making experimentation difficult. Cheers, Stuart CarnieAnonymous
April 28, 2008
Personally, I'd REALLY this to look more like structured typing. I'm pretty much over Attributes and would prefer a way to do DI without Attributes.Anonymous
April 28, 2008
Sounds awesome! I've had to duplicate lots of effort from project to project that requires extensibility of some sort and so can't wait to see what you and the rest of the team cook up. Thanks, Kevin Impacta LLC (http://www.impactalabs.com)Anonymous
April 28, 2008
constructor Injection --> a big YES attributes based mechanism --> a big NOAnonymous
April 28, 2008
Sounds very promising in general, but ... What I still don't get here actually is: What do we have here in addition to using Unity with System.AddIn? Can you put together more explanation about this please? i think it's a FAQ too :).Anonymous
April 28, 2008
Re: Spring.Net as a way of getting where you are trying to go. Perhaps you should think of Spring.Net as going to far in terms of complexity and performance hit - and trying for a target well inside that extreme. Also, why the "bind"? Unless you are trying for a lazy injection or have order of injection issues, it would be great to avoid the "bind" entirely.Anonymous
April 28, 2008
The comment has been removedAnonymous
April 29, 2008
I'll throw a vote in for Compact Framework support in the initial release, but that's probably wishful thinking.Anonymous
April 29, 2008
The comment has been removedAnonymous
April 29, 2008
I will have to agree with the other commenters who want constructor injection. Initially Attributes were appealing and in many cases I still use them but for DI related functionality I much perfer constructor injection. Please do not bake in a dependency on attributes for this scenerio.Anonymous
April 30, 2008
You've been kicked (a good thing) - Trackback from DotNetKicks.comAnonymous
April 30, 2008
The comment has been removedAnonymous
April 30, 2008
The single biggest factor for success on any project I have been apart of in the last 10 years at MicrosoftAnonymous
May 01, 2008
The comment has been removedAnonymous
May 01, 2008
微软建立了一个应用程序框架核心(ApplicationFramework Core)团队,以减少WCF、WPF以及ASP.NET之间的重复。这个团队的目标是为了避免一些设计上的问题,例如WPF与W...Anonymous
May 04, 2008
Personally, I feel you should create a (DI) Container Provider, and then provide a concrete Unity implementation. Microsoft.Mef.Container Microsoft.Met.Container.Unity Others can create their own concrete implementations too (i.e. Spring etc.). Microsoft.Mef.Container.Spring This is exactly what I did when I customized Prism for my needs. And by Provider I mean the one which inherits from ProviderBase, and is specified in a corresponding config section. Not the loose interpertation of the term as Prism currently implements.Anonymous
May 11, 2008
Attributes = No, Autowiring = YesAnonymous
May 11, 2008
I expect all of these maps of dependencies and contributions to be fully dynamic right? Attributes are fun for the demo and simpler apps but are severely limiting for many scenarios. Id like to see evidence of thinking of contributions and dependencies in beyond object references... e.g. event hookups, etc etc. Good luck and keep up the good work~!Anonymous
May 13, 2008
Just lately there seems to be a veritable feast of new blog stuff about VSX (if you don't mind me switchingAnonymous
May 13, 2008
What do you guys think about dynamic activation / deactivation of components coupled with a concept of mandatory / optional extension points: static void Main(string[] args) { var domain = new ComponentDomain(); var hello = new HelloWorld(); // of course this can be implicit domain.AddComponent(hello); domain.AddComponent<OutputDevice>(new CustomOutput()); domain.AddComponent<MessageProcessor>(new TruncateProcessor(2)); domain.Bind(); // bind matches the needs to gives hello.SayIt("Hello"); // => "He" domain.DisableComponent<MessageProcessor>(); hello.SayIt("Hello"); // => "Hello" domain.EnableComponent<MessageProcessor>(); hello.SayIt("Hello"); // => "He" } [Extensible] public class HelloWorld { [ExtensionPoint(typeof(OutputDevice), ExtensionPointImportance.RequiredExtension)] public OutputDevice Output; [ExtensionPoint(typeof(OutputDevice), ExtensionPointImportance.OptionalExtension)] public MessageProcessor Processor; public void SayIt(string message) { string output = message; output = Processor.Process(output); // Here some magic must happen internally if the extension was not provided or is not active :o/ lol Output.WriteLine(output); } } // Extension Contract [ExtensionContract] public abstract class OutputDevice { public abstract void WriteLine(string output); } [ExtensionContract] public abstract class MessageProcessor { public abstract string Process(string input); } [Extension] public class CustomOutput : OutputDevice { public override void WriteLine(string output) { Console.WriteLine(output); } } [Extension] public class TruncateProcessor : MessageProcessor { private int truncateLength; public TruncateProcessor(int truncateLength) { this.truncateLength = truncateLength; } public override string Process(string input) { return input.Substring(0, truncateLength); } } Crazy idea ? :)Anonymous
May 14, 2008
The comment has been removedAnonymous
May 18, 2008
【原文地址】 Managed Extensibility Framework 【原文发表日期】 28 April 08 06:14 Krzysztof 最近在他的blog上宣布 ,我们已经开始致力于为Anonymous
May 31, 2008
Krzysztof recently announced on his blog that we have begun working on an extensibility framework forAnonymous
June 01, 2008
My name is David Kean and I'm a software developer at Microsoft in Redmond. There I work on the ManagedAnonymous
June 03, 2008
After accidentally losing my last personal domain and blog to an ‘advertising’ company that has now becomeAnonymous
June 04, 2008
I’m pleased to announce that we’ve just released a Community Technology Preview (CTP) ofAnonymous
June 04, 2008
Congratulations to the MEF (Managed Extensibility Framework) team who just released their first CTP!Anonymous
June 04, 2008
Today was a big day for my team because we released the bits for the first CTP of the Managed ExtensibilityAnonymous
June 04, 2008
There is TechEd in Orlando, and this means, that there are a lot of new announcements. Let’s fill upAnonymous
June 04, 2008
There is TechEd in Orlando, and this means, that there are a lot of new announcements. Let’s fill upAnonymous
June 05, 2008
Wow.... I´m developing with my team a similar solution for mobile devices (.NETCF). But we have some differences. First we develop a really compact DI container. In our case we have all the metadata in different xml's, each module has several XML's (similar to OSGi). This XML's of the module declare the inputs and outputs, of the module. The module also declares which inputs it needs, and we add a new concept that is the state of the input. Now each developer develops his module with the corresponding XML. Now we are building an Application designer in which where the user select’s which modules will be include in the final application. The designer checks all the dependencies are correct, and then we compile this xml in a CF dll, for performance issues (with codeDom). An then all dynamic injection is done in runtime between modules :). It’s great this will be include in .NET Framework.! We will see the progress of this project. Count with us for testing, and comments form Argentina! Regards, Mariano VicarioAnonymous
June 05, 2008
Several members of my team have already spilled the beans, but yes (!) we just released our first publicAnonymous
June 07, 2008
Krzysztof Cwalina announced that Microsoft has released a CTP of its Managed Extensibility FrameworkAnonymous
June 10, 2008
The comment has been removedAnonymous
June 10, 2008
Eric, I happy to engage in a discussion, as you might be pointing to good issues. The problem with the comment above is that it does not have enough concretes for me to respond, i.e. acknowledge or defend. For example, I did say that we are thinking about supporting POC, and so I don't understand how it implies that "everything new should somehow be more complex", why do you think that usage of attributes is a proof that it's not thought through, what are the 5 ways of doing the same thing in System namesapce?Anonymous
June 11, 2008
The comment has been removedAnonymous
June 17, 2008
· Everything You Wanted To Know About MVC and MVP But Were Afraid To Ask · Functional Programming inAnonymous
July 16, 2008
About three months ago, we were on the heels of shipping Prism (Composite Application Guidance). At thatAnonymous
July 16, 2008
About three months ago, we were on the heels of shipping Prism (Composite Application Guidance). At thatAnonymous
July 16, 2008
About three months ago, we were on the heels of shipping Prism (Composite Application Guidance). At thatAnonymous
July 16, 2008
Krzysztof, I have written a lot of classes that use constructor injection. I would ideally like a DI system that I can introduce with a minimum of code change. Why should my classes have a dependency on a particular DI system via Import/Export attributes?Anonymous
July 16, 2008
While eating my lunch I was running through google reader and started reading a post from Glen , thisAnonymous
July 17, 2008
Winston, I am trying to find some time to post about the attributes, but it's hard given my upcomming vacations and the need to finish 2nd edition of FDG. But quickly, we want to support attributes for the following reasons:
- We want reusable assemblies with dependencies to be "reflective", i.e. to advertize what dependencies they have and need to be able to run succesfully.
- We want to support classic application add-in scenarios (possibly in addition to the callsic DI scenarios). In application add-in scenarios the add-ins need to be smart and know how to compose themselves (i.e the app user just drops an assembly to a foolder). In the classic Di scenarios, the developer does the composition. We are currently investigating how to support the classic DI scenarios (were we do understan develoers don't want to apply attributes).
Anonymous
July 20, 2008
I have to say that my last year at Microsoft has been a little strange. Since the Acropolis project,Anonymous
July 25, 2008
Pingback from http://www.truewill.net/myblog/index.php/2008/07/25/a_house_dividedAnonymous
August 30, 2008
The comment has been removedAnonymous
September 22, 2008
The comment has been removedAnonymous
September 23, 2008
The comment has been removedAnonymous
September 25, 2008
It's not IoC, It's not MAF, it's not the Manged Entity Framework either :-) So what is it ? There hasAnonymous
September 25, 2008
It's not IoC, It's not MAF, it's not the Manged Entity Framework either :-) So what is itAnonymous
September 25, 2008
It's not an IoC container, It's not MAF, it's not the Managed Entity Framework either :-Anonymous
September 25, 2008
It's not an IoC container, It's not MAF, it's not the Managed Entity Framework either :-Anonymous
September 27, 2008
九月初,微软在CodePlex推出了 Managed Extensibility Framework http://www.codeplex.com/MEF 托管扩展性框架是什么? “托管扩展性框架Anonymous
November 06, 2008
The Managed Extensibility Framework (MEF) is a new feature of .NET 4 (and will work on 3.5 as well) thatAnonymous
November 07, 2008
The Managed Extensibility Framework (MEF) is a new feature of .NET 4 (and will work on 3.5 as well) thatAnonymous
November 20, 2008
Your Story is Submitted - Trackback from DotNetShoutout