I’ve begun experimenting with dependency injection (in particular, MEF) for one of my projects, which has a number of different extensibility points. I’m starting to get a feel for what I can do with MEF, but I’d like to hear from others who have more experience with the technology. A few specific cases:
-
My main use case at the moment is exposing various singleton-like services that my extensions make use of. My Framework assembly exposes service interfaces and my Engine assembly contains concrete implementations. This works well, but I may not want to allow all of my extensions to have access to all of my services. Is there a good way within MEF to limit which particular imports I allow a newly instantiated extension to resolve?
-
This particular application has extension objects that I repeatedly instantiate. I can import multiple types of Controllers and Machines, which are instantiated in different combinations for a Project. I couldn’t find a good way to do this with MEF, so I’m doing my own type discovery and instantiation. Is there a good way to do this within MEF or other DI frameworks?
I welcome input on any other things to watch out for or surprising capabilities you’ve discovered that have changed the way you architect.
Load the extension code in a separate container, and make sure that the restricted parts are not available in that container. Let’s simplify the situation to these classes to construct an example:
The goal is to allow
MyExtensionto importPublicService, but notInternalService. Internal code likeProgramshould be able to import anything. You can achieve that like this:This code will not throw a composition exception. If you now change the import on
MyExtensionto the forbiddenInternalService, you will get a composition exception as desired.A side effect of this set-up is that
PublicServicecannot import any private services either, just likeMyExtension. This kind of makes sense, because otherwise nothing would stopPublicServicefrom exposing a private service via a property.I have used
TypeCatalogfor the example, but in practice you should probably use something like the FilteredCatalog sample.You might just be after the
PartCreationPolicyattribute, which controls whether a part is shared (as in, created only once per container) or instantiated multiple times for each import. You can also specify theRequiredCreationPolicyparameter in an import attribute.If that doesn’t solve your problem, take a look at the PartCreator sample in the MEF sources (though note that it will probably soon be renamed to ExportFactory, it already has been in the silverlight edition of MEF).