Prism模块系统内来自WCF服务

本文关键字:WCF 服务 模块 系统 Prism | 更新日期: 2023-09-27 18:15:29

可以从WCF服务中引导Prism模块系统吗?因为无论我做什么,我的MEF依赖都没有被满足。

例如:

这是我的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;
    }
}

这是我的模块,包含数据库Prism服务的接口:

[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,那么一切都可以正常工作。

Prism模块系统内来自WCF服务

您将不会有任何导入到您的db字段,因为MyService对象不是由容器创建的-它不能由它创建,因为容器实际上是在引导程序中创建的,这是在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.
}

我不确定下面的代码片段是否对您有帮助。我只有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
            });
        }

嗯,似乎解决方案是根本不使用Prism,因为它没有添加任何"模块化"与它的模块。这些模块似乎是纯粹用于视觉应用的概念。

相反,必须钩入WCF"启动"过程并从那里引导MEF容器。关于如何做到这一点的答案是相当复杂的(尽管并不复杂),因为WCF已经有许多扩展/挂钩点。

我使用的答案在Mark Seemann的书 . net 中的依赖注入第7.3章:"组合WCF应用程序"中。

除了把那本书的整章都抄到这个答案里,恐怕这是我能做的最好的了。