通过结构图加载程序集时的上下文
我想以类似于此处所示的方式加载插件然而,加载的程序集似乎不共享相同的上下文。
为了解决这个问题,我只是构建了一个包含两个组件的小尖峰。一个控制台应用程序和一个库。控制台应用程序包含 IPlugin 接口,并且没有对 Plugin dll 的引用。
我正在使用自定义注册约定扫描插件目录:
ObjectFactory.Initialize(x => x.Scan(s =>
{
s.AssembliesFromPath(@"..\Plugin");
s.With(new PluginScanner());
}));
public void Process(Type type, Registry registry)
{
if (!type.Name.StartsWith("P")) return;
var instance = ObjectFactory.GetInstance(type);
registry.For<IPlugin>().Add((IPlugin)instance);
}
这会抛出一个无效的转换异常,提示“无法将插件类型转换为 IPlugin”。
public class P1 : IPlugin
{
public void Start() { Console.WriteLine("Hello from P1"); }
}
此外,如果我只是构造实例(顺便说一下,它工作得很好)并尝试访问插件中的 ObjectFactory ObjectFactory.WhatDoIHave() 显示插件实例和主机实例甚至不共享相同的容器实例。
使用 MEF、Structuremap 进行试验并使用 Assembly.Load("Plugin") 手动加载程序集表明,如果使用 Assembly.Load 加载,则效果很好。有什么想法可以解决此问题以与 StructureMaps 装配扫描一起使用吗?
I want to load plugins in a similar way as shown here however the loaded assemblies seem not to share the same context.
Trying to solve the problem I just build a tiny spike containing two assemblies. One console app and one library. The console app contains the IPlugin interface and has no references to the Plugin dll.
I am scanning the plugin dir using a custom Registration convention:
ObjectFactory.Initialize(x => x.Scan(s =>
{
s.AssembliesFromPath(@"..\Plugin");
s.With(new PluginScanner());
}));
public void Process(Type type, Registry registry)
{
if (!type.Name.StartsWith("P")) return;
var instance = ObjectFactory.GetInstance(type);
registry.For<IPlugin>().Add((IPlugin)instance);
}
Which thows an invalid cast exception saying "can not convert the plugin Type to IPlugin".
public class P1 : IPlugin
{
public void Start() { Console.WriteLine("Hello from P1"); }
}
Further if I just construct the instance (which works fine by the way) and try to access ObjectFactory in the plugin ObjectFactory.WhatDoIHave() shows that plugin instance and host instance don't even share the same container instance.
Experimenting around with MEF, Structuremap and loading the assembly manually whith Assembly.Load("Plugin") shows if loaded with Assembly.Load it works fine. Any ideas how I can fix this to work with StructureMaps assembly scanning?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我找到了解决方案。
采取这样的结构:
所以IPlugin是在core.dll中定义的。我的插件依赖于核心以及我的应用程序。
我的应用程序加载 core.dll 并加载plugin.dll,它将在其插件文件夹中搜索其依赖项。第二次加载 core.dll。
如果我从 Plugin.dll 获取类型并尝试将其转换为核心中的 IPlugin,则应用程序会尝试将 {PluginDir}Core.IPlugin 子类的对象转换为 {AppDir}Core.IPlugin。这将失败,因为接口不同。
这种情况会很好地工作,因为 app.exe 和 plugin.dll 将使用相同的 core.dll。
I found the solution.
Take this structure:
So IPlugin is defined in core.dll. My Plugin has a dependency to the core, as well as my app.
My app loads the core.dll and loads the plugin.dll which will search for its dependency in its plugin folder. Loading core.dll a second time.
If I get a type from Plugin.dll and try to cast it to IPlugin in the core the app tries to cast an object which is subclass of {PluginDir}Core.IPlugin to {AppDir}Core.IPlugin. This will fail because the interfaces are different ones.
This scenario will work fine because both app.exe and plugin.dll wil use the same core.dll.