答案 0 :(得分:15)
我只是尝试尽可能地重新创建您的解决方案,而且我没有这样的问题。 (警告,大量代码示例如下......)
第一个项目是应用程序,它包含一个类:
public class PluginLoader : ILoader
{
private List<Type> _providers = new List<Type>();
public PluginLoader()
{
LoadProviders();
LoadConsumers();
}
public IProvider RequestProvider(Type providerType)
{
foreach(Type t in _providers)
{
if (t.GetInterfaces().Contains(providerType))
{
return (IProvider)Activator.CreateInstance(t);
}
}
return null;
}
private void LoadProviders()
{
DirectoryInfo di = new DirectoryInfo(PluginSearchPath);
FileInfo[] assemblies = di.GetFiles("*.dll");
foreach (FileInfo assembly in assemblies)
{
Assembly a = Assembly.LoadFrom(assembly.FullName);
foreach (Type type in a.GetTypes())
{
if (type.GetInterfaces().Contains(typeof(IProvider)))
{
_providers.Add(type);
}
}
}
}
private void LoadConsumers()
{
DirectoryInfo di = new DirectoryInfo(PluginSearchPath);
FileInfo[] assemblies = di.GetFiles("*.dll");
foreach (FileInfo assembly in assemblies)
{
Assembly a = Assembly.LoadFrom(assembly.FullName);
foreach (Type type in a.GetTypes())
{
if (type.GetInterfaces().Contains(typeof(IConsumer)))
{
IConsumer consumer = (IConsumer)Activator.CreateInstance(type);
consumer.Initialize(this);
}
}
}
}
显然,这可以大大整理。
下一个项目是共享库,它包含以下三个接口:
public interface ILoader
{
IProvider RequestProvider(Type providerType);
}
public interface IConsumer
{
void Initialize(ILoader loader);
}
public interface IProvider
{
}
最后有一个包含这些类的插件项目:
public interface ITest : IProvider
{
}
public class TestConsumer : IConsumer
{
public void Initialize(ILoader loader)
{
ITest tester = (ITest)loader.RequestProvider(typeof (ITest));
}
}
public class TestProvider : ITest
{
}
应用程序和插件项目都引用共享项目,插件dll被复制到应用程序的搜索目录中 - 但它们不会相互引用。
当构造PluginLoader时,它会找到所有的IProviders然后创建所有IConsumers并调用它们的Initialize。在初始化内部,消费者可以从加载器请求提供者,并且在此代码的情况下,构造并返回TestProvider。所有这些对我来说都是有效的,没有花哨的控制装配的装载。
答案 1 :(得分:4)
它仍在开发中,但听起来像是MEF的完美用例(包含在.Net 4中),并在VS2010内部使用。
MEF提供了一个简单的解决方案 运行时可扩展性问题。直到 现在,任何想要的应用程序 支持所需的插件模型 从中创建自己的基础架构 刮。那些插件经常是 特定于应用程序,但不可能 重复使用多个 的实施方式。
预览已在http://www.codeplex.com/MEF
上提供Glen Block的blog也很有用。
答案 2 :(得分:2)
您可能会发现我的文章对于查看插件框架的工作示例很有用,以及如何通过创建包含接口的公共程序集来解决这些问题:
C#Basic教程中的插件:
http://www.codeproject.com/KB/cs/pluginsincsharp.aspx
后续文章,启用了Generics插件管理器库:
http://www.codeproject.com/KB/cs/ExtensionManagerLibrary.aspx
答案 3 :(得分:0)
如果您有疑问,两个不相关的程序集如何共享同一个接口,答案是“您不能”解决方案是在所有程序集中包含接口,也许在插件构建器可以引用的dll中,并在装载组件中。
答案 4 :(得分:0)
我做了类似于你想要做的事情,只要我在自动装载机看到的地方装配了组件,我就没有遇到任何问题。
您是否尝试将所有程序集放在exe所在的子目录下?我现在不记得细节,但是有一个步骤列表,记录了加载器查找装配体/类型的确切位置和顺序。