动态加载程序集 [英] Dynamically loading Assembly

查看:23
本文介绍了动态加载程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去,我编写了一个应用程序,它根据数据库中的值动态加载 DLL 及其所有依赖项,如下所示(清理了一些参数)

In the past, I have written an application that dynamically loads a DLL and all of it's dependencies based upon a value in a database, as below (sanitised some parameters)

VB

Dim oType As System.Type
Dim oAssembly As System.Reflection.Assembly
Dim oObject As System.Object
oAssembly = Assembly.LoadFrom(path)
oType = oAssembly.GetType("LogicValidator")
oObject = Activator.CreateInstance(oType)

oObject.Initialise("param1", "param2", "param3", AuditTrail, UserInfo, workingDir)
Console.WriteLine("Begin processing...")
oObject.ProcessBatch(cm_uid)

现在,当我用 C# 编写类似的东西时,在构建应用程序之前会出现一个错误,说明如下:

Now, when I write something similar in C#, an error is present before building the application, stating the following:

C#

System.Type oType = default(System.Type);
System.Reflection.Assembly oAssembly = default(System.Reflection.Assembly);
System.Object oObject = null;
oAssembly = Assembly.LoadFrom(path);
oType = oAssembly.GetType("LogicValidator");
oObject = Activator.CreateInstance(oType);
oObject.Initialise("param1", "param2", "param3", AuditTrail, UserInfo, workingDir);
Console.WriteLine("Begin processing...");
oObject.ProcessBatch(cm_uid);

错误

object"不包含Initialise"的定义,并且找不到接受object"类型的第一个参数的扩展方法Initialise"(您是否缺少 using 指令或程序集引用?)
'object' does not contain a definition for 'Initialise' and no extension method 'Initialise' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

如果某个方法在运行时加载,我的 C# 应用程序如何在编译前识别该方法不存在?

How can my C# application identify that a method does not exist before compiling, if it is loaded at runtime?

编辑

为了帮助偶然发现这个问题的其他人,我删除了以下内容.虽然它确实指出了答案,但其他人的回答更为雄辩.:-)

I have struck out the below for the purposes of helping others who stumble across this question. Whilst it does point to the answer, others have answered it more eloquently. :-)

我想补充一点,以下内容有效 - 但前提是加载的程序集依赖项已经存在.

I would like to add, that the below works - but only if the loaded assemblies dependencies are already present.

var DLL = Assembly.LoadFile(path);
Type type = DLL.GetType("LogicValidator");
dynamic c = Activator.CreateInstance(type);
c.Initialise("param1", "param2", "param3", audit, UserInfo, workingDir);
Console.WriteLine("Begin processing...");
c.ProcessBatch(cm_uid);

推荐答案

如果您在编译时不知道类型,您可以通过将类型声明为 dynamic 来利用动态运行时:

If you don't know the type at compile time you can make use of the dynamic runtime by declaring the type to be dynamic:

var oAssembly = Assembly.LoadFrom(path);
var oType = oAssembly.GetType("LogicValidator");
dynamic oObject = Activator.CreateInstance(oType);
oObject.Initialise("param1", "param2", "param3", AuditTrail, UserInfo, workingDir);
Console.WriteLine("Begin processing...");
oObject.ProcessBatch(cm_uid);

但是,您可能会考虑一种方法,其中加载的类型实现已知接口(将在加载项和您的代码都引用的程序集中声明):

However, you might consider an approach where the loaded type implements a known interface (which would be declared in an assembly that is referenced both by the add-in and your code):

public interface IProcessor
{
    void Initialise(
        string param1, 
        string param2, 
        string param2, 
        AuditTail auditTrail, 
        UserInfo userInfo, 
        DirectoryInfo workingDir);

    void ProcessBatch(int uid);
}

然后您可以按如下方式创建实例并获得完整的 IntelliSense 支持和类型检查:

You can then create an instance as follows and get full IntelliSense support and type checking:

var oAssembly = Assembly.LoadFrom(path);
var oType = oAssembly.GetType("LogicValidator");
IProcessor oObject = Activator.CreateInstance(oType);
oObject.Initialise("param1", "param2", "param3", AuditTrail, UserInfo, workingDir);
Console.WriteLine("Begin processing...");
oObject.ProcessBatch(cm_uid);  

这篇关于动态加载程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆