如果我只有DLL名称和类名,而不在项目中添加对程序集的引用,是否可以在运行时实例化对象?该类实现了一个接口,所以一旦我实例化该类,我将把它转换为接口.
大会名称:
library.dll
类型名称:
Company.Project.Classname
编辑:我没有DLL的绝对路径,所以Assembly.LoadFile
不会工作.DLL可能位于应用程序根目录,system32中,甚至可能已加载到GAC中.
是.您需要使用Assembly.LoadFrom
将程序集加载到内存中,然后可以使用它Activator.CreateInstance
来创建首选类型的实例.您需要先使用反射查看类型.这是一个简单的例子:
Assembly assembly = Assembly.LoadFrom("MyNice.dll"); Type type = assembly.GetType("MyType"); object instanceOfMyType = Activator.CreateInstance(type);
如果您具有程序集文件名和类型名称,则可以使用Activator.CreateInstance(assemblyName, typeName)
.NET类型解析将其解析为类型.您可以使用try/catch包装它,这样如果它失败,您可以搜索目录,您可以专门存储其他可能无法搜索的程序集.这将使用前面的方法.
考虑不同Load*
方法的局限性.来自MSDN文档......
LoadFile不会将文件加载到LoadFrom上下文中,也不会像LoadFrom方法那样使用加载路径解析依赖关系.
有关加载上下文的更多信息,请参阅LoadFrom
文档.
Activator.CreateInstance应该工作.
IFace object = (IFace)Activator.CreateInstance( "AssemblyName", "TypeName" ) .Unwrap();
注意:类型名称必须是完全限定类型.
例:
var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap(); aray.Add(10); foreach (object obj in aray) { Console.WriteLine(obj); }
我发现这个问题和一些答案非常有用,但是我确实遇到了路径问题,因此这个答案将涵盖通过查找bin目录路径来加载库.
第一解决方案
string assemblyName = "library.dll"; string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName); Assembly assembly = Assembly.LoadFrom(assemblyPath); Type T = assembly.GetType("Company.Project.Classname"); Company.Project.Classname instance = (Company.Project.Classname) Activator.CreateInstance(T);
二解决方案
string assemblyName = "library.dll"; string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName); Assembly assembly = Assembly.LoadFile(assemblyPath); (Company.Project.Classname) instance = (Company.Project.Classname) assembly.CreateInstance("Company.Project.Classname");
您可以对接口使用相同的原则(您将创建一个类但是转换为接口),例如:
(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");
此示例适用于Web应用程序,但类似可用于桌面应用程序,例如,仅以不同方式解析路径
Path.GetDirectoryName(Application.ExecutablePath)