I have decided to use MEF for a plugin pattern I have and found MEF easy to pick up and not intrusive at all. I loo开发者_StackOverflowked at samples and found them very easy to work with.
However, as soon as started implementing, I started struggling with the composition. Let's say I have a Class which has [ImportMany]
on one of its properties. All examples I have seen, they create the Container in the class which has imports (let's call it composable) and basically the class composes itself. That might be OK for an example but surely putting knowledge of how the plugin gets populated is too much for the composable to know.
I can happily create a singleton container and access it in my composable but again the composable has to explicitly call Compose()
on itself and I am not happy with that either as it is like a dependency injection scenario where the class pro-actively calls the Resolve()
on the container. So I do not want to use it for just Service Location.
To make the matters worse I am also using Windsor Castle for DI and I am not sure how MEF and Windsor must work together.
I have really looked around and have not been able to find any guidance and sample on how to do MEF right. Now it might be that I have not looked around or I do not know MEF well enough (which is true) but will value your views from the experience of actually using it in the real world.
Do not do that. I used MEF
for my last project and I wish to not do that.
There's a good idea behind it (composition) and I was do that manually for years. I was happy for the first official version in .NET 4.0 but there a re still a lot of design problems.
Unfortunately it's part of Microsoft policy to leave testing and bug finding to end users and feedback the hard-earned bugs and suggestions.
MEF
is good if you use the way the example says. As soon as you need a little change you will find there's not enough documentation and nobody will answer you. Here are some of my never resolved issues with MEF
and you can find my questions in codeplex.com which never had been answered by the developer team:
1) How to pass parameters to part's constructors (they may say use ExportFactory
which is shipped in codeplex version but I wasted a long time on this, and I can say there's not an acceptable solution for that)
2) How to set configurations for parts ? (I ended-up passing configurations to parts through a method which is a bad idea, but the best available)
3) MEF
is very slow because it use reflection under the hood. For my case loading 1,000 parts takes 60 seconds.
4) Debugging is awesome. You get unclear messages. You will end-up downloading the full source from codeplex and search your exceptions inside the code.
After all I think if you have other choices, let MEF
gets mature and use the next version.
I just shared my own experience.
The recommended pattern is for you to create the container once in your hosting code, and only access it from there to get the "root" part. You would call container.GetExport<Root>()
if it's OK for MEF to create the part for you, otherwise you would call container.SatisfyImports(root)
.
The root part should import the things it needs, and the parts supplying those exports should import what they need, and so on. MEF will create the whole graph and none of the parts need to call into the container directly. The samples often have very few different parts, so it isn't always obvious that the container creation and composition should only occur once, even in more complex applications.
There are situations where you may have object that need their imports satisfied, but can't be created by MEF. An example of this is WPF/Silverlight UI objects that are created by the Xaml parser. In this case you might resort to a service which allows these objects to request that their imports be satisfied.
I don't have much advice for how to use MEF and another DI container in the same application. If there isn't much interaction between the parts of the system composed with MEF and Windsor it might work without much trouble. If you need components from one container to be injected with components from the other container, it won't be as simple. One way would be to have a service that a component would have to call to resolve its dependencies from the other container. The other possibility would be to have the containers themselves linked. You can do this in theory with MEF by writing an ExportProvider that accesses the Windsor container. In practice it would require a very deep level of knowledge about MEF, and it might not be possible to get it to work exactly how you'd like.
精彩评论