WCF服务中的棱镜模块系统?

时间:2013-05-24 19:35:57

标签: c# .net wcf prism mef

你能从WCF服务中提升Prism模块系统吗? 因为无论我做什么,我的MEF依赖都没有实现。

E.g:

这是我的 WCF服务实施

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();
    }
}

这是我的 Prism boostrapper ,带有MEF风味:

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;
    }

}

以下是模块,其中包含数据库棱镜服务的接口

[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 ...
}

最后这里是 Prism数据库服务本身:

[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 ...
}

过去几个小时尝试过这个但没有成功。我的db导入始终为null,并且永远不会初始化。

请注意,如果我在没有Prism的情况下完成所有这些操作,那么一切都有效,但只能使用MEF。

3 个答案:

答案 0 :(得分:3)

您的db字段中没有导入任何内容,因为MyService对象不是由容器创建的 - 它不能由它创建,因为容器实际上是在bootstrapper,它位于MyService的构造函数中。

解决此问题的一种简单方法是在初始化容器后满足对象的导入。为此,您可以在引导程序中公开容器,如下所示:

public class MyServiceBoostrapper
{
    public CompositionContainer MyServiceContainer
    {
        get { return Container; }
    }

    // Rest of bootstrapper definitions...
}

然后修改MyService的构造函数:

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

    // This is an extension method. You'll need to add
    // System.ComponentModel.Composition to your using statements.
    bootstrapper.MyServiceContainer.SatisfyImportsOnce(this);

    // At this stage, "db" should not be null.
}

答案 1 :(得分:1)

我不确定以下代码段会对您有所帮助。我只有PRISM和Unity的经验。试试吧,告诉我发生了什么。

protected override void ConfigureContainer()
    {
        base.ConfigureContainer();

        this.RegisterTypeIfMissing(typeof(IDatabase), typeof(DatabaseImpl ), true);
    }

您也在创建并清空ModuleCatalog,从不配置它。

protected override void ConfigureModuleCatalog()
        {

            base.ConfigureModuleCatalog();

            var moduleCatalog = (ModuleCatalog)ModuleCatalog;

            Type Initial = typeof(ModuleActivator);
            moduleCatalog.AddModule(new ModuleInfo
            {
                ModuleName = Initial.Name,
                ModuleType = Initial.AssemblyQualifiedName
            });
        }

答案 2 :(得分:0)

嗯,似乎解决方案似乎根本不使用Prism,因为它没有添加任何东西"模块化"用它的模块。看起来这些模块纯粹是为了视觉应用而设计。

相反,人们必须挂钩到WCF" startup"程序并从那里加强MEF容器。关于如何做到这一点的答案相当复杂(虽然并不复杂),因为WCF已经有很多扩展/挂钩点。

我使用的答案在于Mark Seemann在第7.3章中的 .NET中的依赖注入一书:"撰写WCF应用程序"。

如果没有将整本章从这本书复制到这个答案中,我担心这是我能做的最好的事情。