Search code examples
c#.netwcfprismmef

Prism module system from within WCF service?


Can you boostrap a Prism module system from within the WCF service? Because no matter what I do my MEF dependencies are not being fulfilled.

E.g.:

This is my WCF service implementation

public class MyService : IMyServiceContract{
    // This should get filled by MEF after Prism loads the required modules
    [Import]
    IDatabase db;

    public MyService(){
        var bootsrapper = new MyServiceBoostrapper();
        bootsrapper.Run();
    }
}

This is my Prism boostrapper with MEF flavor:

public class MyServiceBoostrapper : MefBootstrapper
{
    protected override void ConfigureContainer()
    {
        base.ConfigureContainer();
    }

    protected override IModuleCatalog CreateModuleCatalog()
    {
        return new ConfigurationModuleCatalog();
    }
    protected override void ConfigureAggregateCatalog()
    {
        base.ConfigureAggregateCatalog();

        // TODO: Add this assembly ... don't know why
        this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(MyServiceBoostrapper).Assembly));
        this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(IDatabase).Assembly));
        // This is what provides the service
        this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(DatabaseImpl).Assembly));
    }

    protected override DependencyObject CreateShell()
    {
        // we don't need the shell
        return null;
    }

}

Here is my module that contains the interfaces for Database Prism service :

[ModuleExport(typeof(IDatabase))]
public class ModuleActivator : IModule
{
    public void Initialize()
    {
        // Do nothing as this module simply provides the API.
    }
}
public interface IDatabase
{
  // interface methods here ...
}

and lastly here is the Prism database service itself:

[ModuleExport(typeof(DatabaseImpl), DependsOnModuleNames = new string[] { "IDatabase" })]
public class ModuleActivator : IModule
{
    public void Initialize()
    {
        // Do nothing as this is a library module.
    }
}

[Export(typeof(IDatabase))]
public class DatabaseImpl : IDatabase
{
   /// implementation here ...
}

Tried this for the last few hours with no success. My db import is always null and is never initialized.

Note, that everything works if I do all of this without Prism, but only with MEF.


Solution

  • Well, it seems like the solution is not to use Prism at all, as it does not add anything "modular" with it's modules. It seems like the modules are concepts purely for visual applications.

    Instead, one has to hook into the WCF "startup" procedure and boostrap the MEF container from there. The answer on how to do this is rather involved (though not complicated), as WCF already has many extension/hook-in points.

    The answer I used lies in the book Dependency Injection in .NET by Mark Seemann in Chapter 7.3: "Composing WCF applications".

    Short of copying the whole chapter from that book into this answer, I'm afraid that's the best I can do.