0

我正在尝试按照此处建议的实现为我们的 WPF 程序实现插件架构。我希望我的插件位于与主程序文件夹不同的文件夹中。我已经让它只能部分工作。这是代码:

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

我目前正在使用的插件具有以下注册表,如您所见,我正在覆盖注册表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))并没有找到 plugin-type 的任何注册类型IPluginBase。我已经尝试调用这些方法,IPrintProgramExecutor并且肯定它们返回了具体类型。找了好久的原因,没找到。

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

更新:

  1. 切换到我的笔记本电脑后,以前有效的拦截不再有效。此外,我现在遇到一个异常,即PluginRegistry找不到我尝试注册的程序集之一:

StructureMap.StructureMapException:无法为注册表类型“Extensions.Automation.PluginRegistry”创建实例。详情请查看内部异常---> System.Reflection.TargetInvocationException: 异常已被调用的目标抛出。---> System.IO.FileNotFoundException:无法加载文件或程序集“Automation.Servers.Interfaces,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。该系统找不到指定的文件。在 Extensions.Automation.PluginRegistry..ctor() ...

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

4

1 回答 1

0

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

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

于 2016-10-20T10:49:29.533 回答