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

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

装配名称:

库 dll

键入名称:

公司,项目,课程名称


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

213002 次浏览

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

是的。我现在没有任何我亲自做过的例子。等我找到了再发。基本上,您将使用反射来加载程序集,然后拉取您需要的任何类型。

与此同时,这个链接应该可以让你开始:

使用反射在运行时加载未引用的程序集

是的,您需要在 Assembly 类上使用静态 Load 方法,然后调用从调用 Load 返回给您的 Assembly 实例上的 CreateInstance 方法。

此外,还可以根据需要调用 Assembly 类上以“ Load”开头的其他静态方法之一。

((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod();

是的。需要使用 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 包装它,这样如果它失败了,您就可以执行对目录的搜索,在这些目录中您可以专门存储其他可能无法搜索的程序集。此时将使用前面的方法。

根据这种功能对于项目的固有程度,您可能需要考虑类似于 MEF的东西,它将为您负责组件的加载和绑定。

可以使用 * Assembly 加载程序集。加载 * * 方法。使用 Activator.CreateInstance可以创建所需类型的新实例。请记住,您必须使用要加载的类的完整类型名称(例如 名称空间。子名称空间。类名称)。使用 类型类的方法 调用成员,您可以对类型调用方法。

另外,考虑到一旦加载,程序集在整个 AppDomain 被卸载之前不能被卸载(这基本上是内存泄漏)。

考虑不同 Load*方法的局限性。

LoadFile 不像 LoadFrom 方法那样使用加载路径将文件加载到 LoadFrom 上下文和 不解决依赖关系中。

关于加载上下文的更多信息可以在 LoadFrom文档中找到。

你可以这样做:

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

我发现这个问题和一些答案非常有用,但是我确实有路径问题,所以这个答案将涵盖通过查找 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)
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");


Type type = assembly.GetType("MyType");


dynamic instanceOfMyType = Activator.CreateInstance(type);

因此,通过这种方式,您可以使用函数而不是获取 methodinfo,然后调用它。您将像这样做 instanceOfMyType。方法名称() ; 但是不能使用 Intellisense,因为动态类型是在运行时而不是在编译时键入的。

很简单。

来自 MSDN 的例子:

public static void Main()
{
// 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);
}

这里有一个参考链接

Https://msdn.microsoft.com/en-us/library/25y1ya39.aspx

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

我使用.net5(. net core 5)。我需要做的是:

    static void Main()
{
//...


AppDomain.CurrentDomain.AssemblyResolve += CciBaseResolveEventHandler;


Application.Run(new FormMain());
}


private static Assembly CciBaseResolveEventHandler(object sender, ResolveEventArgs args)
{
return Assembly.LoadFile($@"{Directory.GetCurrentDirectory()}\{nameof(CciBase)}.dll");
}
  1. 将“ CciBase”更改为 dll 名称。
  2. 确保 dll 与 exe 在同一个文件夹中。
  3. 在主进程启动之前执行此操作(Application.Run ())。