我正在尝试按照提议的实现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(...)
注册了一些东西?非常感谢帮助!
更新
PluginRegistry
中注册的一个程序集找不到: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
进行调试?希望有人可以帮助我。我慢慢地失去了它。
答案 0 :(得分:0)
您应该能够看到StructureMap尝试探测具有扫描诊断类型的程序集的位置:http://structuremap.github.io/diagnostics/type-scanning/
您可以指定文件夹,而不是依赖AppDomain / AppContext。