我可以在运行时加载一个.NET程序集并实例化只知道名称的types吗?
是否有可能在运行时实例化一个对象,如果我只有DLL名称和类名,而不添加对项目中的程序集的引用? 这个类实现了一个接口,所以一旦我实例化这个类,我就会将它转换到接口。
大会名称:
library.dll
types名称:
Company.Project.Classname
编辑:我没有DLL的绝对path,所以Assembly.LoadFile
将无法正常工作。 该DLL可能位于应用程序根目录system32中,甚至可能在GAC中加载。
是。 您需要使用Assembly.LoadFrom
将程序集加载到内存中,然后可以使用Activator.CreateInstance
创build首选types的实例。 您需要先使用reflection来查看types。 这是一个简单的例子:
Assembly assembly = Assembly.LoadFrom("MyNice.dll"); Type type = assembly.GetType("MyType"); object instanceOfMyType = Activator.CreateInstance(type);
更新
如果具有程序集文件名和types名称,则可以使用Activator.CreateInstance(assemblyName, typeName)
来请求.NETtypesparsing将其parsing为types。 你可以用try / catch来包装它,如果失败了,你可以执行一个目录search,在那里你可以专门存储其他可能不被search的程序集。 这将使用前面的方法。
考虑不同的Load*
方法的局限性。 从MSDN文档…
LoadFile不会像LoadFrom方法那样将文件加载到LoadFrom上下文中, 也不会使用加载path来parsing依赖关系 。
有关Load Context的更多信息可以在LoadFrom
文档中find。
Activator.CreateInstance应该工作。
IFace object = (IFace)Activator.CreateInstance( "AssemblyName", "TypeName" ) .Unwrap();
注意:types名称必须是完全限定的types。
例:
var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap(); aray.Add(10); foreach (object obj in aray) { Console.WriteLine(obj); }
我发现这个问题和一些答案非常有用,但是我确实有path问题,所以这个答案将涵盖通过查找bin目录path加载库。
第一个scheme
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);
第二种scheme
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");
你可以使用相同的原则为接口(你将创build一个类,但铸造到接口),如:
(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");
这个例子是为web应用程序,但类似的可以用于桌面应用程序,例如,只有path以不同的方式解决
Path.GetDirectoryName(Application.ExecutablePath)
是。 我现在没有任何我个人可用的例子。 我稍后会发现一些。 基本上你会使用reflection来加载程序集,然后拉取你需要的任何types。
同时,这个链接应该让你开始:
使用reflection在运行时加载未引用的程序集
((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod();
您可以使用* Assembly.Load **方法加载程序集。 使用Activator.CreateInstance你可以创build你想要的types的新实例。 请记住,您必须使用要加载的类的完整types名称(例如Namespace.SubNamespace.ClassName )。 使用Type类的方法InvokeMember可以调用types的方法。
另外,考虑到一旦加载,程序集不能被卸载,直到整个AppDomain也被卸载(这基本上是一个内存泄漏)。
取决于这种function对于你的项目来说有多么内在,你可能需要考虑一些类似于MEF的东西,它们会负责为你加载和捆绑组件。
从Framework v4.5开始,您可以使用Activator.CreateInstanceFrom()轻松实例化程序集中的类。 以下示例显示如何使用它以及如何调用传递参数并获取返回值的方法。
// Assuming moduleFileName contains full or valid relative path to assembly var moduleInstance = Activator.CreateInstanceFrom(moduleFileName, "MyNamespace.MyClass"); MethodInfo mi = moduleInstance.Unwrap().GetType().GetMethod("MyMethod"); // Assuming the method returns a boolean and accepts a single string parameter bool rc = Convert.ToBoolean(mi.Invoke(moduleInstance.Unwrap(), new object[] { "MyParamValue" } ));
是的,你需要在Assembly类上使用静态Load方法,然后调用从调用Load返回给你的Assembly实例的CreateInstance方法。
此外,您可以根据您的需要调用其他静态方法,从Assembly类的“Load”开始。
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll"); Type type = assembly.GetType("MyType"); dynamic instanceOfMyType = Activator.CreateInstance(type);
所以这样你可以使用函数而不是获取methodinfo,然后调用它。你会这样做instanceOfMyType.MethodName(); 但是不能使用Intellisense,因为dynamictypes是在运行时键入的,而不是在编译时。
你可以这样做:
using System.Reflection; Assembly MyDALL = Assembly.Load("DALL"); //DALL name of your assembly Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // name of your class object obj = Activator.CreateInstance(MyLoadClass);
这很容易
根据MSDN
公共静态无效的主要()
// Use the file name to load the assembly into the current // application domain. Assembly a = Assembly.Load("example"); // Get the type to use. Type myType = a.GetType("Example"); // Get the method to call. MethodInfo myMethod = myType.GetMethod("MethodA"); // Create an instance. object obj = Activator.CreateInstance(myType); // Execute the method. myMethod.Invoke(obj, null);
在这里它的参考链接