当前位置:  开发笔记 > 编程语言 > 正文

我可以在运行时加载.NET程序集并实例化只知道名称的类型吗?

如何解决《我可以在运行时加载.NET程序集并实例化只知道名称的类型吗?》经验,为你挑选了4个好方法。

如果我只有DLL名称和类名,而不在项目中添加对程序集的引用,是否可以在运行时实例化对象?该类实现了一个接口,所以一旦我实例化该类,我将把它转换为接口.

大会名称:

library.dll

类型名称:

Company.Project.Classname


编辑:我没有DLL的绝对路径,所以Assembly.LoadFile不会工作.DLL可能位于应用程序根目录,system32中,甚至可能已加载到GAC中.



1> Jeff Yates..:

是.您需要使用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包装它,这样如果它失败,您可以搜索目录,您可以专门存储其他可能无法搜索的程序集.这将使用前面的方法.


这有助于......将其标记为已接受的答案?
我没有dll的绝对路径,所以assemlby.LoadFile等.不工作,还有其他想法吗?
@MegaByte:LoadFrom与LoadFile不同。它将解析您的依赖关系,并且应从已知路径(GAC,exe目录等)解析DLL名称。有关更多信息,请参见MSDN。

2> Anthony Mast..:

考虑不同Load*方法的局限性.来自MSDN文档......

LoadFile不会将文件加载到LoadFrom上下文中,也不会像LoadFrom方法那样使用加载路径解析依赖关系.

有关加载上下文的更多信息,请参阅LoadFrom文档.


很好地抓住了这里的差异,谢谢!

3> tvanfosson..:

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);
}



4> Sofija..:

我发现这个问题和一些答案非常有用,但是我确实遇到了路径问题,因此这个答案将涵盖通过查找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)

推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有