【发布时间】:2017-04-04 17:59:14
【问题描述】:
我正在尝试制作一个小型 C# 工具来比较两个 svn 修订版本并跟踪任何类中的属性更改。我的目标是在不使用 Momo.Cecil 的情况下使用反射来比较我的 dll 的每个类的属性。
通过实验,然后阅读这篇文章 Assembly Loading 和在 Google 上找到的一些线程,我了解到如果我们不使用 Assembly.ReflectionOnlyLoadFrom,两个具有相同身份的 DLL 将被解析为相同。
尝试使用他们的代码为每次加载创建一个 AppDomain,并尝试从搜索中获得许多变体,我得到了这个异常,我找不到任何线程来解释如何解决这个问题:
API 限制:程序集 'file:///D:\somepath\82\MyLib.dll' 已从其他位置加载。无法从同一应用域中的新位置加载。
此错误发生在以下行的第二次调用(路径 82)上:
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
也许我不了解一些非常基本的东西,这使我无法正确创建新的 AppDomain?
这是用于重现此问题的所有代码。
我的入口点的代码
//Let say one of the property has been renamed between both commits
var svnRev81Assembly = ReflectionOnlyLoadFrom(@"D:\somepath\81\MyLib.dll");
var svnRev82Assembly = ReflectionOnlyLoadFrom(@"D:\somepath\82\MyLib.dll");
加载器的实现
private string _CurrentAssemblyKey;
private Assembly ReflectionOnlyLoadFrom(string assemblyPath)
{
var path = Path.GetDirectoryName(assemblyPath);
// Create application domain setup information.
AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ApplicationBase = path;
domaininfo.PrivateBinPath = path;
_CurrentAssemblyKey = Guid.NewGuid().ToString();
AppDomain currentAd = AppDomain.CreateDomain(_CurrentAssemblyKey, null, domaininfo); //Everytime we create a new domain with a new name
//currentAd.ReflectionOnlyAssemblyResolve += CustomReflectionOnlyResolver; This doesnt work anymore since I added AppDomainSetup
currentAd.SetData(_CurrentAssemblyKey, path);
//Loading to specific location - folder 81 or 82
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
//Preloading the
foreach (var assemblyName in assembly.GetReferencedAssemblies())
{
Assembly.ReflectionOnlyLoadFrom(Path.Combine(path, assemblyName.Name + ".dll"));
}
Type[] types = assembly.GetTypes();
// Lastly, reset the ALS entry and remove our handler
currentAd.SetData(_CurrentAssemblyKey, null);
//currentAd.ReflectionOnlyAssemblyResolve -= CustomReflectionOnlyResolver; This doesnt work anymore since I added AppDomainSetup
return assembly;
}
【问题讨论】:
标签: c# .net .net-assembly appdomain