.net核心应用程序中包含三个版本。
Solution.Models.Customer:
public class Customer : ICustomer
{
public void Get()
{
Console.WriteLine("Message!");
}
}
Solution.Interfaces.ICustomer:
public interface ICustomer
{
void Get();
}
Solution.Creator.ContainerCreator:
public class ContainerCreator
{
Assembly _assembly;
public void Add(Assembly assembly)
{
_assembly = assembly;
}
public object CreateInstance(Type type)
{
object instance;
var classesInfo = GetClassesInfo();
//classes Info looks for a match in the assembly with the passed parameter.
var result = classesInfo.Where(w => w.ClassType.FullName == type.FullName).FirstOrDefault();
var objectType = result.ClassType;
instance = Activator.CreateInstance(objectType);
return instance;
}
}
然后,当我创建类型为( ICustomer )的对象时,会成功创建 ,但是如果我强制转换为( Customer >)类型,则发生异常- System.InvalidCastException 。
var files = Directory.GetFiles(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
"Solution.Models.dll",
SearchOption.TopDirectoryOnly);
var asm = Assembly.LoadFile(files[0]);
ContainerCreator containerCreator = new ContainerCreator();
containerCreator.Add(asm);
// Success
Customer = (ICustomer)containerCreator.CreateInstance(typeof(Customer));
// System.InvalidCastException
//Customer = (Customer)containerCreator.CreateInstance(typeof(Customer));
我在做什么错,我该如何打败这个例外?
答案 0 :(得分:1)
注意:我认为OP正在尝试创建某种插件。如果是这样,我建议您使用许多自定义库,而不是自己创建轮子,而是使用已经实现的东西
当人们在运行时第一次开始使用程序集时,这是一个非常常见的错误。到那儿去了吗:)问题是您正在使用Assembly.LoadFile
将程序集加载到您的应用程序域中。无需赘述,即使您使用Assembly.LoadFile
加载相同的dll,程序集中定义的类型也将被视为不同。假设我有程序集A
../MyFolder/A.dll
public class MyType;
public class MyAnotherType;
....
var aDll = Assembly.LoadFile("A.dll");
var aDllAgain = Assembly.LoadFile("A.dll");
var myTypeFromADll =aDll.GetType("MyType");
var myTypeFromADllAgain = aDllAgain.GetType("MyType");
//Yes this is of type MyType but since you used LoadFile
//It is of type MyType from a_dll code base
var instanceFromADll = Activator.CreateInstance(myTypeFromADll);
//Yes this is of type MyType but since you used LoadFile
//It is of type MyType from a_dll_again code base
var instanceFromADllAgain = Activator.CreateInstance(myTypeFromADllAgain);
因此,您正在获取InvalidCastException,因为您试图将X类型的实例转换为Y类型。
解决方案很简单。您应该使用Assemly.Load
方法,如果不能,那么请使用Assembly.LoadFrom
。除非您完全知道自己在做什么,否则请远离Assembly.LoadFile
。
这里是一个很好的详细解释。 Best practices