在我正在处理的一个项目中,我创建了一个AppDomain
并告诉它加载当前正在执行的程序集。然后我调用Activator.CreateInstanceFrom
来创建一个内部类(类型MyType
)的编组实例(你可以看到它也使用相同的装配位置):
ObjectHandle handle = Activator.CreateInstanceFrom(
Factory.operatingDomain,
Assembly.GetExecutingAssembly().Location,
typeof(MyType).FullName,
false,
BindingFlags.NonPublic | BindingFlags.Instance,
null,
new object[] { config },
null,
null);
当我对这个程序集进行单元测试时,一切正常,但是在 ASP.NET 调试环境中使用它时,它会抛出一个MissingMethodException
. 我花时间创建了我自己的扩展类,Binder
看看会发生什么。唯一的区别似乎是在调试环境中,传入的参数 ( config
) 从位于常规目录的程序集中ParameterInfo
获取其类型,而对象从位于 ASP.NET 临时文件夹中的程序集获取其类型。
即使我通过了typeof(config).Assembly.Location
,我也会得到相同的结果。所以它是框架内部的东西。
除了保留一个利基使用的内部可访问的自定义绑定器之外,我能做些什么来纠正这个问题,当参数类型匹配时返回 true FullName
?
更新
我尝试传递从应用程序域加载的程序集中获取的程序集的位置,但仍然没有骰子。我的自定义活页夹也不起作用——它需要我实现 Binder.ChangeType 我发现我什至无法从一种类型转换为另一种类型(尽管如前所述,它们之间的唯一区别是位置大会的。)
更新 2
我尝试了以下代码以确保应用程序域从正确的位置加载正确的程序集:
if (binPath != String.Empty)
{
Factory.operatingDomain.SetData("assemblyLocation", Assembly.GetExecutingAssembly().Location);
Factory.operatingDomain.DoCallBack(() =>
{
String location = AppDomain.CurrentDomain.GetData("assemblyLocation").ToString();
String filename = System.IO.Path.GetFileName(location);
List<String> paths = AppDomain.CurrentDomain.RelativeSearchPath.Split(';').ToList();
foreach (String path in paths.ToArray())
{
paths.Remove(path);
paths.AddRange(System.IO.Directory.GetFiles(path, filename));
}
Assembly.LoadFrom(paths[0]);
});
}
这是正确的!它加载了正确的程序集!但在这里,稍晚一点:
String location = Factory.operatingDomain
.GetAssemblies()
.Single(a => a.FullName == Assembly.GetExecutingAssembly().FullName)
.Location;
这将返回 .NET 临时文件夹路径。那是不对的。我会认为这是框架中的一个错误!