我在Assembly A中有以下类。程序集引用了StructureMap 2.6.1。
public static class Bootstrapper
{
public static void Bootstrap(string databaseName)
{
StructureMapBootstrapper.Bootstrap(databaseName);
}
}
我在一个完全不同的程序集(B)中引用程序集A,并且在调用此行时遇到以下运行时错误:
Bootstrapper.Bootstrap(db);
运行时错误是:
FileNotFoundException:无法加载文件或程序集“StructureMap,Version = 2.6.1.0,Culture = neutral,PublicKeyToken = e60ad81abae3c223”或其依赖项之一。系统找不到指定的文件。
我经常不得不将StructureMap.dll复制到Assembly B的bin目录中。这非常令人讨厌。有关如何解决此问题的任何建议?有人知道AssemblyB需要AssemblyA引用的程序集的一般规则吗?
谢谢!
感谢您的快速回复!我想过简单地添加StructureMap作为参考。然而,我在设计中采用的角度是从消费者那里抽象出底层实现。换句话说,程序集B对于最终使用StructureMap这一事实一无所知。另外,如果我是GAC StructureMap,那么我会遇到部署问题吗?如果我将站点部署到其全局缓存中没有StructureMap的主机,那么我将回到原点。我很好奇,鉴于这个程序集引用问题,如何实现真正的抽象。
答案 0 :(得分:2)
有一个名为Refix的优秀工具可用于检查和修复依赖项。
答案 1 :(得分:1)
为避免复制DLL,您可以将StructureMap.dll添加到项目中,并在构建AssemblyA时让VS自动将其复制到输出。
或者,您可以使用ILMerge将StructureMap.dll合并到程序集B中,而不必担心复制它,因为程序集B将包含所需的所有IL。
或者,您可以将StructureMap.dll添加到全局程序集缓存中,这应该允许.NET在不必复制的情况下找到它。但是,IIRC,所有GAC集会都需要强有力的名称。
答案 2 :(得分:0)
顺便说一句,由于程序集具有强名称(您可以通过它具有PublicKeyToken
的值来看到这一点),您可以将StructureMap程序集安装到GAC中,将使它可用于系统上运行的任何.NET应用程序。这可能会解决您的问题。
至于在GAC中使用程序集进行部署,这取决于您计划部署的方式。我假设这是一个Winforms应用程序,所以我也假设你将通过一个安装项目进行部署。如果是这种情况,那么很容易在项目中包含应该放在GAC中的程序集,如果它不存在,它将安装在那里。
回答你的问题,程序集绑定和加载有些细微差别,但通用规则是在第一次加载包含的类型时加载程序集。只要引用的代码块位于活动堆栈帧上,就会加载类型。
最后一句话基本归结为:当发生以下任何一种情况时,会加载一个类型:
例如,假设我有A
,B
和C
类型。
public class A
{
}
public class C
{
}
public class B
{
private A myA;
private static C myC;
}
当加载类型B
时,它也会加载A
,因为它被用作实例变量,C
将被加载,因为它被用作静态变量。
答案 3 :(得分:0)
如果您希望程序集B不知道对StructureMap的依赖性,但也避免每次手动复制文件,您可以添加StructureMap作为程序集A的引用(正如其他人所说)并将两个项目的构建输出路径设置为相同的目录(通过Project Properties-> Build选项卡)。这样,当A组装也能“看到”它时。