如果我将引用项目的 Copy Local 设置为 false,则主项目无法找到程序集
我正在尝试开发一个使用插件的应用程序。我有一个用于主应用程序的项目,一个用于插件可以/必须使用的常见元素,一个用于测试插件。主项目和测试插件项目都引用了公共元素。如果我将 Copy Local 设置为 true,那么我会得到公共元素的三个副本(当我有更多插件时,情况会更糟),我认为这会扰乱反射。当主程序尝试反映应用于测试插件中的类的自定义属性(共同定义)时,
Object[] attributes = pluginType.GetCustomAttributes(typeof(PluginAttribute), true);
我找不到该属性,但当我找到时:
Object[] attributes = pluginType.GetCustomAttributes(true);
该属性出现在列表中。我猜这是因为主程序和测试插件从不同的程序集中获取 PluginAttribute,因此它们不被视为同一事物。
解决方案似乎是关闭“复制本地”。但是,当我这样做时,我收到一个运行时错误,即程序找不到包含公共元素的程序集。我如何告诉运行时去哪里寻找它?
任何帮助将不胜感激!
编辑:
好的,这是该场景的更多细节。
我的解决方案中有三个项目。一个是 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";
}
}
}
主机在 TestPlugin
程序集中找到 TestClass
一切正常,但我在访问 PluginAttribute 时遇到问题。我的猜测是,这是因为我有 Common.dll
的三个副本,并且主机使用 ./Host/bin/ 中的副本时出现问题Debug
但 TestClass
可能是使用 ./Host/bin/Debug/Plugins
中的副本构建的,这是一个物理上不同的 dll(这是否使其成为不同的程序集,或者只是另一个副本相同的 dll?)所以为了跟进这个猜测,我尝试将 Copy Local 设置为 false,所以我在 ./Common/bin/Debug
中只得到了 Common.dll
的一个副本。构建得很好,但给了我一个运行时错误,它无法加载通用程序集。
I'm trying to develop an application that uses plugins. I have one project for the main application, one for common elements that plugins can/must use, and one for a test plugin. The main project and the test plugin project both reference the common elements. If I leave Copy Local set to true then I get three copies of the common elements (it will be worse when I have more plugins), and I think it's messing up reflection. When the main program tries to reflect on a custom attribute (defined in common) applied to a class in the test plugin using
Object[] attributes = pluginType.GetCustomAttributes(typeof(PluginAttribute), true);
I don't find the attribute, but when I do:
Object[] attributes = pluginType.GetCustomAttributes(true);
the attribute appears in the list. I'm guessing that's because because the main program and the test plugin are getting PluginAttribute from different assemblies so they're not seen as the same thing.
The solution would seem to be to turn off Copy Local. When I do that, though, I get a runtime error that the program can't find the assembly containing the common elements. How do I tell the runtime where to look for it?
Any help would be much appreciated!
Edit:
Ok, here's some more detail of the scenario.
I have three projects in the solution. One is for a dll, let's call it Common, that I leave in the directory that VS chooses for it, so the dll ends up in ./Common/bin/Debug
. The dll contains definitions of an interface that all plugins should implement: something like
namespace Common
{
[ContractClass(typeof(PluginContract))]
public interface IPlugin
{
String Foo();
}
}
It also contains definition of an attribute class that can be applied to plugins, something like:
public class PluginAttribute: Attribute
{
public String Bar {get; protected set;}
public PluginAttribute(String bar)
{
this.Bar = bar;
}
}
The next project is the Host, which is an executable. Again, that's in the default directory, so the executable is in ./Host/bin/Debug
. That searches for assemblies in ./Host/bin/Debug/Plugins
, and uses reflection to search each assembly for classes that implement IPlugin. If it does, then I use the code I quoted above to see if it has PluginAttribute set.
The final project is a test plugin, which I have set to build to ./Host/bin/Debug/Plugins
.
namespace TestPlugin
{
[PluginAttribute("Test Class")]
public class TestClass: IPlugin
{
public string Foo()
{
return "Foo";
}
}
}
Host is finding TestClass
in the TestPlugin
assembly just fine, but I'm having trouble accessing the PluginAttribute. My guess is that this is because I have three copies of Common.dll
, and that there's an issue with Host using the copy in ./Host/bin/Debug
but TestClass
is presumably built with the copy in ./Host/bin/Debug/Plugins
, a physically different dll (does that make it a different assembly, or is it just another copy of the same dll?) So to follow up that guess I tried setting Copy Local to false, so I only got one copy of Common.dll
in ./Common/bin/Debug
. That builds just fine, but gives me a runtime error that it can't load the Common assembly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您想告诉运行时程序集的位置,您可以使用应用程序域的私有 binpath。
http://msdn.microsoft.com/en-us/library /system.appdomain.appendprivatepath.aspx
抱歉,我没有完全了解您所面临的情况。这只是一个告诉程序集位置的解决方案。
If you want to tell the runtime about the location of the assembly you can use the private binpath of app domain.
http://msdn.microsoft.com/en-us/library/system.appdomain.appendprivatepath.aspx
Sorry I didn't get the scenario exactly what you are facing.This is just a solution to tell the assembly location.