迁移到.net 4后,我们开始面对库的问题.假设我们有我们的库MyLib.dll,它引用了Interop程序集Interop.dll.Interop.dll引用了MissingInterop.dll.
所以引用可以显示为: MyLib.dll -> Interop.dll -> MissingInterop.dll
在MyLib.dll中,我们只使用Interop.dll中的部分类,因此我们永远不会调用任何需要MissingInterop.dll的内容,并且在.net 3.5中它运行正常这就是为什么我们不使用MyLib.dll发送MissingInterop.dll.
当我们在.net 4下运行的进程使用MyLib.dll时,应用程序失败,并出现以下异常:
FileNotFoundException:"无法加载文件或程序集'MissingInterop.dll,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其依赖项之一.系统找不到指定的文件."
另外我注意到Interop.dll引用了其他缺少的dll但是.net不会尝试加载它们.我发现了差异.MissingInterop.dll中的某些类型用于Interop.dll中的方法参数,而来自其他缺失库的类型仅用作方法返回类型,即在Interop.dll中我可以看到:
Class C1
MethodA : void (valuetype [MissingInterop]MissingAssembly.TypeA&)
Class C2
get_Status : valuetype[AnotherMissingInterop]AnotherMissingAssembly.TypeB()
Run Code Online (Sandbox Code Playgroud)
和.NET 4尝试加载MissingInterop.dll但不尝试加载AnotherMissingInterop.dll.
.NET 3.5没有尝试加载MissingInterop.dll和AnotherMissingInterop,因为它们没有在执行路径中使用.
我知道.NET 4有新的Fusion,但我没有在任何地方找到这样的突破性变化.有谁知道为什么.NET 4会尝试加载不需要的东西?有没有办法解决这个问题,而无需重新编译代码或添加丢失的文件?
我现在正在与AssenblyResolve活动挣扎一段时间.我搜索了stackoverflow并做了其他谷歌搜索,并尝试了所有我认为相关的.以下链接更接近我的问题(在我看来):
我有一个带有静态方法的Bootstrapper类(我将删除我们拥有的线程安全代码,只是为了清楚起见:
public static void Initialize()
{
AppDomain.CurrentDomain.AssemblyResolve += CustomResolve;
}
private static Assembly CustomResolve(object sender, ResolveEventArgs args)
{
// There is a lot code here but basicall what it does.
// Is determining which architecture the computer is running on and
// extract the correct embedded dll (x86 or x64). The code was based
// on milang on GitHub (https://github.com/milang/P4.net). And it's the same
// purpose we want to be able to load the x86 or x64 …Run Code Online (Sandbox Code Playgroud) 我真的很努力找到一个类似的问题来获得一些线索,但似乎没有人描述我们所拥有的情况,所以在这里.
背景
我们的产品具有以下一般设计:
[本地安装文件夹]
[GAC]
在ClientAPI.dll中,我们有一个入口点,我们需要调用最终用户项目.让我们来称呼它Initialize().
我们首先要做的Initialize是使用事件在当前域上安装所谓的程序集解析处理程序AssemblyResolve.这个处理程序将知道如何定位实现dll并使用它们将它们加载到客户端进程中Assembly.Load().
考虑控制台应用程序.它看起来像:
class Class1
{
void Main(string[] args)
{
ClientAPI.Initialize();
// Use other API's in the assembly, possibly internally referencing the
// implementation classes, that now will be resolved by our assembly
// resolve handler.
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在控制台/ Windows窗体/ WPF世界中一切都很好.我们的程序集解析处理程序已正确安装和调用,一旦ClientAPI.dll需要其功能,它就可以成功解析对实现DLL的引用.
问题陈述
话虽如此,我们打算不仅支持控制台或WPF应用程序,因此我们依赖于ASP.NET中的相同设计.因此,在VS 2010中创建一个新的ASP.NET Web应用程序项目,我们认为一切都会像以下一样简单:
class Globals : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
ClientAPI.Initialize();
// ... …Run Code Online (Sandbox Code Playgroud) 我知道可以注册到 AppDomain.AssemblyResolve 事件来处理在自动 CLR 搜索失败时加载程序集的尝试。
在我当前的项目中,通过这种机制处理所有程序集加载会很有帮助;有没有办法做到这一点?
一个(丑陋的)解决方法是将可执行文件移动到一个单独的目录中,并让所有内容都由 AssemblyResolve 委托处理;我希望有一个更清洁的解决方案。
问候, 安德里亚
我正在尝试通过反射动态加载程序集。我有这样的文件夹结构:
project
\-- BIN
|-- myApp.exe
|-- SOMEEXTENTION1
| |-- someExtention1.dll
| \-- itsDependency1.dll
|
|-- SOMEEXTENTION2
|-- someExtention2.dll
\-- itsDependency2.dll
Run Code Online (Sandbox Code Playgroud)
我可以使用反射加载一些扩展。在执行过程中someExtention查找itsDependency时会出现问题。点网在 BIN 文件夹中查找。它在那里找不到它。Appdomain 的 AssemblyResolve 事件被引发...
我正在捕获这个事件。在 ResolveEventArgs 中,我获取需要加载的程序集的名称。问题是我没有得到 RequestingAssembly。ResolveEventArgs 的该属性始终为空。我需要请求程序集,以便我可以直接查看其自己的 EXTN 文件夹。如果没有它,我必须查看所有 EXTN 文件夹,就我而言,这些文件夹可能非常大。
RequestingAssembly 有一个属性 Location,根据这篇 msdn 文章,它包含物理文件的路径。本文还介绍了该属性可能为 Nothing 的情况。我不明白那里讨论的负载上下文。
任何帮助将不胜感激...