为什么我的插件类型仅在这种情况下被部分注册?

时间:2016-10-14 15:23:34

标签: c# wpf mvvm structuremap4

我正在尝试按照提议的实现here为我们的WPF程序实现插件架构。我希望我的插件驻留在主程序文件夹的单独文件夹中。我已经让它只是部分工作。这是代码:

计划是为每个插件提供自己的StructureMap注册表来覆盖默认的StructureMap regstry。

我目前正在处理的插件有以下注册表,正如您所看到的,我正在覆盖插件类型IPrintProgramExecutor的注册表,以拦截并使用AutomationController。并且可以正常工作

public class PluginRegistry : Registry
{
    public PluginRegistry()
    {
        this.ForConcreteType<AutomationController>()
            .Configure
            .Ctor<IPrintProgramExecutor>().Is(c=> c.GetInstance<PrintProgramExecutor>())
            .Singleton();
        this.For<IAutomationController>().Use(c => c.GetInstance<AutomationController>()).Singleton();
        this.For<IPrintProgramExecutor>().Use(c => c.GetInstance<IAutomationController>()).Singleton();
        //this.ForConcreteType<AutomationPlugin>()
        //    .Configure
        //    .Singleton();
        this.For<IPluginBase>().Use<AutomationPlugin>();
    }
}

AutomationPlugin目前是这个存根:

public class AutomationPlugin : IPluginBase
{
    public ViewModelBase ViewModel {
        get { return viewModel; }
        private set { viewModel = value; }
    }
    public ResourceDictionary View { get; }

    private ViewModelBase viewModel { get; set; }
    private ResourceDictionary viewDictionary = new ResourceDictionary();

    public AutomationPlugin()
    {
         // do something meaningfull!
    }
}

IPluginBase

public interface IPluginBase
{
    ViewModelBase ViewModel { get; }
    ResourceDictionary View { get; }
}

添加注册表的类是这样的,其中pluginPath是扩展文件夹的路径:

public class PluginRegistryAdder : Registry
{
    public PluginRegistryAdder(string pluginPath)
    {
        Scan( x =>
        {
            x.AssembliesFromPath(pluginPath);
            x.LookForRegistries();
        });
    }
}

使用上面代码实际绑定插件注册表的类是:

public static class ExtensionManager
{
    public static void RegisterPluginsInDic(string pluginPath, IContainer container)
    {
        var pluginRegistries = new PluginRegistryAdder(pluginPath);
        container.Configure(_ => _.IncludeRegistry(pluginRegistries));
        var whatIHave = container.WhatDoIHave(typeof(IPluginBase));
        var plugins = container.Model.GetAllPossible<IPluginBase>(); // the IEnumberable plugins is empty although I am registering `AutomationPlugin` for it. Why?!
    }
}

现在,如上所述,插件类型IPrintProgramExecutor的拦截按预期工作。但由于某种原因,container.Model.GetAllPossible<IPluginBase>()container.WhatDoIHave(typeof(IPluginBase))找不到插件类型IPluginBase的任何注册类型。我试过为IPrintProgramExecutor调用这些方法,当然它们会返回具体类型。我一直在寻找相当长的一段时间,却找不到它。

任何想法为什么?这可能与事实有关,我打电话container.Configure(...)两次,也许事实是我第一次拨打IPringProgramExecutor时已经为container.Configure(...)注册了一些东西?非常感谢帮助!

更新

  1. 切换到我的笔记本电脑后,之前有效的拦截不再有效。此外,我现在得到一个例外,我试图在PluginRegistry中注册的一个程序集找不到:
  2.   

    StructureMap.StructureMapException:无法为注册表类型&#39; Extensions.Automation.PluginRegistry&#39;创建实例。请查看内部异常以获取详细信息    ---&GT; System.Reflection.TargetInvocationException:调用目标抛出了异常。 ---&GT; System.IO.FileNotFoundException:无法加载文件或程序集&#39; Automation.Servers.Interfaces,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#39;或其中一个依赖项。该系统找不到指定的文件。      在Extensions.Automation.PluginRegistry..ctor()      ...

    总而言之,这似乎是一个我无法弄清楚的路径问题。我怀疑,在运行时程序尝试从主路径加载插件注册表中的DLL,但相应的DLL / asseblies驻留在Extension-folder中。如何从StructureMap尝试加载程序集Automation.Servers.Interfaces进行调试?希望有人可以帮助我。我慢慢地失去了它。

1 个答案:

答案 0 :(得分:0)

您应该能够看到StructureMap尝试探测具有扫描诊断类型的程序集的位置:http://structuremap.github.io/diagnostics/type-scanning/

您可以指定文件夹,而不是依赖AppDomain / AppContext。

相关问题