我正在尝试开发一个使用插件的应用程序。我有一个主应用程序项目,一个用于插件可以/必须使用的常用元素,另一个用于测试插件。主项目和测试插件项目都引用了共同的元素。如果我将Copy Local设置为true,那么我会得到三个共同元素的副本(当我有更多插件时会更糟),而且我认为这会弄乱反射。当主程序尝试使用
反映应用于测试插件中的类的自定义属性(通用定义)时Object[] attributes = pluginType.GetCustomAttributes(typeof(PluginAttribute), true);
我找不到属性,但是当我这样做时:
Object[] attributes = pluginType.GetCustomAttributes(true);
该属性出现在列表中。我猜这是因为主程序和测试插件从不同的程序集中获取PluginAttribute所以它们看起来不一样。
解决方案似乎是关闭Copy Local。但是,当我这样做时,我得到一个运行时错误,程序无法找到包含公共元素的程序集。如何告诉运行时在哪里查找它?
非常感谢任何帮助!
编辑:
好的,这里是该场景的更多细节。
我在解决方案中有三个项目。一个用于dll,我们称之为Common,我将其保留在VS为其选择的目录中,因此dll最终在./Common/bin/Debug
中。 dll包含所有插件应实现的接口的定义:类似
namespace Common
{
[ContractClass(typeof(PluginContract))]
public interface IPlugin
{
String Foo();
}
}
它还包含可应用于插件的属性类的定义,如:
public class PluginAttribute: Attribute
{
public String Bar {get; protected set;}
public PluginAttribute(String bar)
{
this.Bar = bar;
}
}
下一个项目是Host,它是一个可执行文件。同样,这是在默认目录中,因此可执行文件位于./Host/bin/Debug
中。它在./Host/bin/Debug/Plugins
中搜索程序集,并使用反射搜索每个程序集以查找实现IPlugin的类。如果是,那么我使用上面引用的代码来查看它是否设置了PluginAttribute。
最终项目是一个测试插件,我已将其设置为./Host/bin/Debug/Plugins
。
namespace TestPlugin
{
[PluginAttribute("Test Class")]
public class TestClass: IPlugin
{
public string Foo()
{
return "Foo";
}
}
}
主机正在TestClass
程序集中找到TestPlugin
就好了,但是我无法访问PluginAttribute。我的猜测是因为我有Common.dll
的三个副本,并且主机使用./Host/bin/Debug
中的副本存在问题,但TestClass
可能已构建使用./Host/bin/Debug/Plugins
中的副本,一个物理上不同的dll(这会使它成为一个不同的程序集,还是只是同一个dll的另一个副本?)所以为了跟进那个猜测我尝试将Copy Local设置为false,所以我Common.dll
只收到了./Common/bin/Debug
的一份副本。这构建得很好,但是给了我一个运行时错误,它无法加载Common程序集。
答案 0 :(得分:0)
如果要告知运行时有关程序集位置的信息,可以使用app域的私有binpath。
http://msdn.microsoft.com/en-us/library/system.appdomain.appendprivatepath.aspx
很抱歉,我没有准确了解您所面对的情况。这只是一个告诉装配位置的解决方案。