如何将程序集引用添加到加载的程序集?
How to add assemblies reference to a loaded assembly?
我正在使用 .NET 反射来检查程序集的内容。不幸的是,在检查由我的程序集引用但在别处定义的类型时,这并不是那么简单。
所以,假设我有两个 Assembly
:
Assembly assembly1 = Assembly.LoadFrom("MyAssembly.dll");
Assembly assembly2 = Assembly.LoadFrom("MyReferencedAssembly.dll");
在 assembly1
中有在 assembly2
中定义的类型所以我想要的基本上是将 assembly2
加载到 assembly1
.
如何以编程方式实现这一点?
正在尝试使用 AppDomain.Load
按照评论中的建议,我正在尝试这样做:
private Assembly GetAssembly()
{
string[] referencedAssemblyPaths = new[] { "MyReferencedAssembly.dll" };
var domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase = Environment.CurrentDirectory;
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
var domain = AppDomain.CreateDomain("AssemblyContextDomain", adevidence, domaininfo);
Assembly assembly = domain.Load(LoadFile("MyAssembly.dll"));
foreach (var path in referencedAssemblyPaths)
{
domain.Load(LoadFile(path));
}
return assembly;
}
private static byte[] LoadFile(string filename)
{
FileStream fs = new FileStream(filename, FileMode.Open);
byte[] buffer = new byte[(int)fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
return buffer;
}
但是我在调用 domain.Load(LoadFile("MyAssembly.dll"))
时遇到问题,因为我得到 FileNotFoundException
:
Could not load file or assembly 'MyAssembly, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
调试信息 通过调试我可以看到文件存在于正确的位置,LoadFile
成功 returns 流。问题出在抛出该异常的 AppDomain.Load
中。
- 为什么提示找不到文件?
- 它是否正在尝试加载依赖项,而那些是它找不到的文件?但是我会在之后加载依赖项...
我到底应该如何加载程序集及其依赖项?
加载程序集时,.Net 会自动尝试加载所有依赖项。 FileNotFoundException 可能指的是 'one of its dependencies' 而不是实际的程序集文件 - 您可以使用融合日志记录 (How to enable assembly bind failure logging (Fusion) in .NET) 来确定确切的失败原因。正如评论中所建议的,您可以使用 AppDomain.AssemblyResolve 来提供额外的逻辑来查找引用的程序集,但是您需要实际将事件附加到您的域,而我在您的代码中看不到 - 所以 domain.AssemblyResolve += ...
。这通常仅在引用的程序集位于不同的文件夹中或默认搜索模式找不到时才有必要,因此如果您所追求的只是调试为什么它不会加载,那么融合日志就是关键。
AppDomains 可能有点棘手,这就是为什么它们 replaced/not 在 .Net Core (https://blogs.msdn.microsoft.com/dotnet/2016/02/10/porting-to-net-core/) 中实现的原因。
如果您只想加载程序集以首先检查它,而不加载所有依赖项,您可以加载它仅用于反射 - https://msdn.microsoft.com/en-us/library/0et80c7k.aspx,这将不允许您执行任何代码在装配中,因此您需要在稍后的某个时间点进行实际加载。
我正在使用 .NET 反射来检查程序集的内容。不幸的是,在检查由我的程序集引用但在别处定义的类型时,这并不是那么简单。
所以,假设我有两个 Assembly
:
Assembly assembly1 = Assembly.LoadFrom("MyAssembly.dll");
Assembly assembly2 = Assembly.LoadFrom("MyReferencedAssembly.dll");
在 assembly1
中有在 assembly2
中定义的类型所以我想要的基本上是将 assembly2
加载到 assembly1
.
如何以编程方式实现这一点?
正在尝试使用 AppDomain.Load
按照评论中的建议,我正在尝试这样做:
private Assembly GetAssembly()
{
string[] referencedAssemblyPaths = new[] { "MyReferencedAssembly.dll" };
var domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase = Environment.CurrentDirectory;
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
var domain = AppDomain.CreateDomain("AssemblyContextDomain", adevidence, domaininfo);
Assembly assembly = domain.Load(LoadFile("MyAssembly.dll"));
foreach (var path in referencedAssemblyPaths)
{
domain.Load(LoadFile(path));
}
return assembly;
}
private static byte[] LoadFile(string filename)
{
FileStream fs = new FileStream(filename, FileMode.Open);
byte[] buffer = new byte[(int)fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
return buffer;
}
但是我在调用 domain.Load(LoadFile("MyAssembly.dll"))
时遇到问题,因为我得到 FileNotFoundException
:
Could not load file or assembly 'MyAssembly, Version=10.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
调试信息 通过调试我可以看到文件存在于正确的位置,LoadFile
成功 returns 流。问题出在抛出该异常的 AppDomain.Load
中。
- 为什么提示找不到文件?
- 它是否正在尝试加载依赖项,而那些是它找不到的文件?但是我会在之后加载依赖项...
我到底应该如何加载程序集及其依赖项?
加载程序集时,.Net 会自动尝试加载所有依赖项。 FileNotFoundException 可能指的是 'one of its dependencies' 而不是实际的程序集文件 - 您可以使用融合日志记录 (How to enable assembly bind failure logging (Fusion) in .NET) 来确定确切的失败原因。正如评论中所建议的,您可以使用 AppDomain.AssemblyResolve 来提供额外的逻辑来查找引用的程序集,但是您需要实际将事件附加到您的域,而我在您的代码中看不到 - 所以 domain.AssemblyResolve += ...
。这通常仅在引用的程序集位于不同的文件夹中或默认搜索模式找不到时才有必要,因此如果您所追求的只是调试为什么它不会加载,那么融合日志就是关键。
AppDomains 可能有点棘手,这就是为什么它们 replaced/not 在 .Net Core (https://blogs.msdn.microsoft.com/dotnet/2016/02/10/porting-to-net-core/) 中实现的原因。
如果您只想加载程序集以首先检查它,而不加载所有依赖项,您可以加载它仅用于反射 - https://msdn.microsoft.com/en-us/library/0et80c7k.aspx,这将不允许您执行任何代码在装配中,因此您需要在稍后的某个时间点进行实际加载。