Модульная система "Призма" в службе WCF?

можете ли вы увеличить систему модулей Prism из службы WCF? Потому что независимо от того, что я делаю, мои зависимости 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();
    }
}

это мой Призма 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 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 ...
}

и наконец вот это служба базы данных 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 ответов


у вас не будет ничего импортированного в ваш 'ы.

один простой способ решить эту проблему-удовлетворить импорт вашего объекта после инициализации контейнера. Для этого вы можете выставить контейнер в загрузчике следующим образом:

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

Я не уверен, что следующие фрагменты помогут вам. У меня есть только опыт с призмой и единством. Просто попробуй и скажи мне, что происходит.

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 уже имеет много точек расширения/подключения.

ответ, который я использовал, лежит в книге инъекция зависимостей в .NET Марк Seemann в главе 7.3: "составление приложений WCF".

за исключением копирования всей главы из этой книги в этот ответ, я боюсь, что это лучшее, что я могу сделать.