C# 我可以在运行时加载 .NET 程序集并实例化只知道名称的类型吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/465488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I load a .NET assembly at runtime and instantiate a type knowing only the name?
提问by MegaByte
Is it possible to instantiate an object at runtime if I only have the DLL name and the class name, without adding a reference to the assembly in the project? The class implements a interface, so once I instantiate the class, I will then cast it to the interface.
如果我只有 DLL 名称和类名,而不在项目中添加对程序集的引用,是否可以在运行时实例化对象?该类实现了一个接口,因此一旦我实例化了该类,我就会将其转换为该接口。
Assembly name:
程序集名称:
library.dll
库文件
Type name:
类型名称:
Company.Project.Classname
公司.项目.类名
EDIT:I dont have the absolute path of the DLL, so Assembly.LoadFile
won't work. The DLL might be in the application root, system32, or even loaded in the GAC.
编辑:我没有 DLL 的绝对路径,所以Assembly.LoadFile
不会工作。DLL 可能位于应用程序根目录、system32 中,甚至可能加载到 GAC 中。
回答by tvanfosson
Activator.CreateInstanceought to work.
Activator.CreateInstance应该可以工作。
IFace object = (IFace)Activator.CreateInstance( "AssemblyName",
"TypeName" )
.Unwrap();
Note:The type name must be the fully qualified type.
注意:类型名称必须是完全限定的类型。
Example:
例子:
var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap();
aray.Add(10);
foreach (object obj in aray)
{
Console.WriteLine(obj);
}
回答by Giovanni Galbo
Yes. I don't have any examples that I've done personally available right now. I'll post later when I find some. Basically you'll use reflection to load the assembly and then to pull whatever types you need for it.
是的。我现在没有任何我亲自做过的例子。等我找到了以后再发。基本上,您将使用反射来加载程序集,然后提取您需要的任何类型。
In the meantime, this link should get you started:
与此同时,这个链接应该让你开始:
回答by casperOne
Yes, it is, you will want to use the static Load method on the Assembly class, and then call then call the CreateInstance method on the Assembly instance returned to you from the call to Load.
是的,是的,您将希望在Assembly 类上使用静态Load 方法,然后在调用Load 返回给您的Assembly 实例上调用然后调用CreateInstance 方法。
Also, you can call one of the other static methods starting with "Load" on the Assembly class, depending on your needs.
此外,您可以根据需要在 Assembly 类上调用以“Load”开头的其他静态方法之一。
回答by abatishchev
((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod();
回答by Jeff Yates
Yes. You need to use Assembly.LoadFrom
to load the assembly into memory, then you can use Activator.CreateInstance
to create an instance of your preferred type. You'll need to look the type up first using reflection. Here is a simple example:
是的。您需要使用Assembly.LoadFrom
将程序集加载到内存中,然后您可以使用它Activator.CreateInstance
来创建您喜欢的类型的实例。您需要先使用反射查找类型。这是一个简单的例子:
Assembly assembly = Assembly.LoadFrom("MyNice.dll");
Type type = assembly.GetType("MyType");
object instanceOfMyType = Activator.CreateInstance(type);
Update
更新
When you have the assembly file name and the type name, you can use Activator.CreateInstance(assemblyName, typeName)
to ask the .NET type resolution to resolve that into a type. You could wrap that with a try/catch so that if it fails, you can perform a search of directories where you may specifically store additional assemblies that otherwise might not be searched. This would use the preceding method at that point.
当您拥有程序集文件名和类型名称时,您可以使用Activator.CreateInstance(assemblyName, typeName)
.NET 类型解析将其解析为类型。您可以使用 try/catch 对其进行包装,以便在失败时执行目录搜索,您可以在其中专门存储其他程序集,否则可能无法搜索到这些程序集。这将在那时使用前面的方法。
回答by Kent Boogaart
回答by Dario Solera
You can load an assembly using *Assembly.Load** methods. Using Activator.CreateInstanceyou can create new instances of the type you want. Keep in mind that you have to use the full type name of the class you want to load (for example Namespace.SubNamespace.ClassName). Using the method InvokeMemberof the Typeclass you can invoke methods on the type.
您可以使用 *Assembly.Load** 方法加载程序集。使用Activator.CreateInstance您可以创建所需类型的新实例。请记住,您必须使用要加载的类的完整类型名称(例如Namespace.SubNamespace.ClassName)。使用方法InvokeMember中的类型类,你可以调用该类型的方法。
Also, take into account that once loaded, an assembly cannot be unloaded until the whole AppDomain is unloaded too (this is basically a memory leak).
另外,请考虑到一旦加载,在整个 AppDomain 也卸载之前无法卸载程序集(这基本上是内存泄漏)。
回答by Anthony Mastrean
Consider the limitations of the different Load*
methods. From the MSDNdocs...
考虑不同Load*
方法的局限性。从MSDN文档...
LoadFile does not load files into the LoadFrom context, and does not resolve dependenciesusing the load path, as the LoadFrom method does.
LoadFile 不会将文件加载到 LoadFrom 上下文中,并且不会像 LoadFrom 方法那样使用加载路径解析依赖项。
More information on Load Contexts can be found in the LoadFrom
docs.
可以在LoadFrom
文档中找到有关加载上下文的更多信息。
回答by Pankaj
You can do this things on this way:
你可以用这种方式做这些事情:
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);
回答by Sofija
I found this question and some answers very useful, however I did have path problems, so this answer would cover loading library by finding bin directory path.
我发现这个问题和一些答案非常有用,但是我确实遇到了路径问题,所以这个答案将通过查找 bin 目录路径来涵盖加载库。
First solution:
第一个解决方案:
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);
Second solution
第二种解决方案
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");
You can use same principle for interfaces (you would be creating a class but casting to interface), such as:
您可以对接口使用相同的原则(您将创建一个类但转换为接口),例如:
(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");
This example is for web application but similar could be used for Desktop application, only path is resolved in different way, for example
此示例适用于 Web 应用程序,但类似的可用于桌面应用程序,只是路径以不同的方式解析,例如
Path.GetDirectoryName(Application.ExecutablePath)