.NET 程序集引用 101
我在程序集 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,版本 = 2.6.1.0 ,Culture=neutral,PublicKeyToken=e60ad81abae3c223' 或其依赖项之一。
我必须不断地将 StructureMap.dll 复制到程序集 B 的 bin 目录中。这非常烦人。有谁知道 AssemblyB 何时需要 AssemblyA 引用的程序集的一般规则?
谢谢!
我考虑简单地添加 StructureMap 作为参考。设计的目的是从消费者那里抽象出底层实现。换句话说,程序集 B 会不知道最终使用了 StructureMap。另外,如果我使用 GAC StructureMap,那么我会遇到部署问题,对吧?如果我将站点部署到其全局缓存中没有 StructureMap 的主机,那么我会回到第一个方向。我很好奇考虑到这个程序集引用问题,如何实现真正的抽象。
I have the following class located in Assembly A. The assembly has a reference to StructureMap 2.6.1.
public static class Bootstrapper
{
public static void Bootstrap(string databaseName)
{
StructureMapBootstrapper.Bootstrap(databaseName);
}
}
I'm referencing Assembly A in a completely different Assembly (B) and I"m getting the following runtime error when this line is called:
Bootstrapper.Bootstrap(db);
The runtime error is:
FileNotFoundException: Could not load file or assembly 'StructureMap, Version=2.6.1.0, Culture=neutral, PublicKeyToken=e60ad81abae3c223' or one of its dependencies. The system cannot find the file specified.
I'm constantly having to copy StructureMap.dll to the bin directory of Assembly B. This is incredibly annoying. Any suggestions on how to resolve this? Does anybody know the general rules regarding when assemblies referenced by AssemblyA will be needed by AssemblyB?
Thanks!
Thanks for the quick replies! I thought about simply adding StructureMap as a reference. However, the angle I was going for in my design was to abstract underlying implementations away from the consumer. In other words, Assembly B would be ignorant to the fact that StructureMap was ultimately being used. Also, if I GAC StructureMap, then I would run into deployment issues right? If I deploy a site to a host machine which doesn't have StructureMap in its Global Cache, then I'm back to square one. I'm curious how true abstraction could be realized given this assembly referencing issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有一个出色的工具,名为 Refix您可以用来检查和修复您的依赖项。
There is an excellent tool called Refix that you could use to inspect and fix your dependencies.
为了避免复制 DLL,您可以将 StructureMap.dll 添加到您的项目中,并让 VS 在构建 AssemblyA 时自动将其复制到输出中。
或者,您可以使用 ILMerge 将 StructureMap.dll 合并到程序集 B 中,而不必担心复制它,因为程序集 B 将包含所需的所有 IL。
或者,您可以将 StructureMap.dll 添加到全局程序集缓存,这样 .NET 就可以找到它,而无需复制它。然而,IIRC,所有 GAC 程序集都需要强名称。
To avoid copying the DLL, you could add the StructureMap.dll to your project and have VS automatically copy it to the output upon building AssemblyA.
Or, you could use ILMerge to merge StructureMap.dll into Assembly B, and not worry about copying it, as Assembly B will contain all the IL needed.
Or, you can add StructureMap.dll to the Global Assembly Cache, which should allow .NET to find it without having to copy it. However, IIRC, all GAC assemblies need strong names.
顺便说一句,由于程序集具有强名称(您可以通过它具有
PublicKeyToken
的值来看到这一点),您可以将 StructureMap 程序集安装到 GAC,这将使其可供系统上运行的任何 .NET 应用程序使用。这可能会解决您的问题。至于在GAC中使用程序集进行部署,这取决于您计划如何部署。我假设这是一个 Winforms 应用程序,因此我还假设您将通过安装项目进行部署。如果是这种情况,那么很容易将应该进入 GAC 的程序集包含在项目中,并且如果它不存在,它将安装在那里。
不过,要回答您的问题,程序集绑定和加载有些细微差别,但一般规则是在第一次加载包含的类型时加载程序集。一旦引用的代码块位于活动堆栈帧上,就会加载类型。
最后一句话本质上可以归结为:当发生以下任一情况时,就会加载一个类型:
例如,假设我有类型
A
、B
和C
。当加载类型
B
时,它也会加载A
因为它被用作实例变量,而C
也会被加载,因为它被用作实例变量静态变量。As an aside, since the assembly has a strong name (you can see this by the fact that it has a value for
PublicKeyToken
), you could install the StructureMap assembly into the GAC, which would make it available to any .NET application running on the system. This will likely solve your problem.As for deploying with the assembly in the GAC, it depends on how you plan to deploy. I'm assuming that this is a Winforms application, so I'm also assuming that you'll be deploying through a setup project. If that's the case, then it's easy to include the assembly that's supposed to go in the GAC in the project, and it will install it there if it isn't present.
To answer your question, though, assembly binding and loading are somewhat nuanced, but the general rule is that an assembly is loaded the first time a type that is contains is loaded. A type is loaded as soon as a block of code that references is on the active stack frame.
The last sentence essentially boils down to this: a type is loaded when either of the following happens:
For example, say I have types
A
,B
, andC
.When type
B
is loaded, it will also loadA
because it's used as an instance variable, andC
will get loaded because it is used as a static variable.如果您希望程序集 B 不知道对 StructureMap 的依赖性,但又避免每次手动复制文件,您可以添加 StructureMap 作为对程序集 A 的引用(正如其他人所说),并将两个项目的构建输出路径设置为同一目录(通过“项目属性”->“构建”选项卡)。这样,程序集 A 也可以“看到”它。
If you want Assembly B to remain unaware of the dependency to StructureMap but also avoid copying the file manually each time, you can add StructureMap as reference to Assembly A (as others have said) and set both projects' build output path to the same directory (via Project Properties->Build tab). This way when Assembly A can "see" it too.