Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why MEF-container isn't available in modules?

In my Prism app, the MEF container is available from within the Bootstrapper class via the Container property.

But it isn't from within the class module (IModule). I may only import the container through IServiceLocator.

Why? I thought that it made sense to use a common interface against concrete technology, but the Prism 4.1 guideline ask us to not use IServiceLocator (in Considerations for Using IServiceLocator).

like image 786
Eugene Avatar asked May 30 '12 11:05

Eugene


1 Answers

I think it corresponds not to Prism or MEF, but to Dependency Injection principle and best practices in general. (Yeah, I knot that MEF isn't DI container, but here it's used almost as DI container, so I suppose to use the same practices here).

In best practices of DI (this book is very cool, I highly recommend it) it's good to have such steps in DI "workflow":

  • register all necessary types (in Prism - by Bootstrapper.ConfigureCatalog() method)
  • resolve root object (with all nested objects. In Prism - by Bootstrapper.CreateShell() method)
  • use your root object
  • release you root object

Ideally, you should NOT use DI container anymore. Your code should NOT know about existance of DI container (from this side Unity is really DI container, because you can write code which will not know about using DI container). If your code knows about it - it DEPENDS on DI container, and it's bad thing.

PS. If you want to use MEF container in your module anyway (for example, because you're not very familiar with DI paradigm or you have some very specific tasks), you can try something like:

[ModuleExport(typeof(YourModule))]
public class YourModule : IModule
{
    public static CompositionContainer CompositionContainer;

    [ImportingConstructor]
    public void YourModule(CompositionContainer container)
    {
        this.CompositionContainer = container;
    }
}

Don't forget to register your MEF container itself in your Boostrapper:

public class YourBootstrapper: MefBootstrapper
{
    protected override CompositionContainer CreateContainer()
    {
        var container = base.CreateContainer();
        container.ComposeExportedValue(container);
        return container;
    }
}
like image 180
chopikadze Avatar answered Oct 23 '22 05:10

chopikadze