我试图从仅在运行时已知的程序集中创建一个类。有奇怪的问题。
string providerType = AppConfig.GetConfigValue("LocationProvider");
string assemblyFileName = AppConfig.GetConfigValue("LocationProviderAssembly");
Assembly assembly = Assembly.LoadFrom(assemblyFileName);
//Object obj = assembly.CreateInstance(providerType) ;
Type type = assembly.GetType(providerType);
Object obj = Activator.CreateInstance(type);
ILocationProvider locProvider = obj as ILocationProvider;
float distance = locProvider.GetDistance(new Location(), new Location());
如果使用调试器,并在执行最后两行之前停止,则可以在“即时”窗口中运行这两行,它们便可以工作。但是,如果我让代码运行,locProvider将保持为空。
obj似乎具有正确的类型:
obj.GetType()
{Name = "LocationProviderConcrete" FullName = "LocationProvider.LocationProviderConcrete"}
[System.RuntimeType]: {Name = "LocationProviderConcrete" FullName = "LocationProvider.LocationProviderConcrete"}
base {System.Reflection.MemberInfo}: {Name = "LocationProviderConcrete" FullName = "LocationProvider.LocationProviderConcrete"}
并在立即窗口中正常工作:
((ILocationProvider) obj).GetDistance(new Location(), new Location())
关于为什么这在正常的代码流中不起作用的任何线索?
最佳答案
ILocationProvider
在哪里声明?我的猜测是,在通过反射加载的程序集中有一个副本,在“运行中”的程序集中有一个副本。这些是不同的接口。
基本上,您需要确保接口仅在一个程序集中加载,并且也仅在该程序集的一个副本中加载。
我在this article年前写的-在某些方面可能有更好的方法,但是出了问题的基本原理仍然有效。