Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 动态加载组件_C#_Vb.net - Fatal编程技术网

C# 动态加载组件

C# 动态加载组件,c#,vb.net,C#,Vb.net,在过去,我编写了一个应用程序,根据数据库中的值动态加载DLL及其所有依赖项,如下所示(清理了一些参数) 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 = Activat

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

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#中编写类似的代码时,在构建应用程序之前会出现一个错误,说明如下:

C#

错误

“object”不包含“Initialise”的定义,并且找不到接受“object”类型的第一个参数的扩展方法“Initialise”(是否缺少using指令或程序集引用?) 如果某个方法是在运行时加载的,我的C#应用程序如何在编译之前识别它不存在

编辑

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

我想补充一点,下面的方法是有效的,但前提是加载的程序集依赖项已经存在

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

您需要将
oObject
数据类型更改为
动态
,如下所示:

System.Type oType = default(System.Type);
System.Reflection.Assembly oAssembly = default(System.Reflection.Assembly);
dynamic 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);

有关
dynamic
的详细信息:

如果在编译时不知道类型,可以通过将类型声明为
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);

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

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

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

您不需要像其他答案所说的那样将其强制转换为动态,您还可以继续使用反射,反射不会调用DLR,在这种情况下应该更快,特别是因为您已经加载了必要的反射对象:

var oAssembly = Assembly.LoadFrom(path);
var oType = oAssembly.GetType("LogicValidator");
var oObject = Activator.CreateInstance(oType);
var oInitialiseMethod = oType.GetMethod("Initialise"); //See note below the code.
var oProcessBatchMethod = oType.GetMethod("ProcessBatch"); //See note below the code.
oInitialiseMethod.Invoke(oObject, "param1", "param2", "param3", AuditTrail, UserInfo, workingDir);
Console.WriteLine("Begin processing...");
oObject.ProcessBatch(cm_uid);
您需要对Type.GetMethod使用重载,该方法接受函数参数的类型[],以便签名匹配。我是为你做的,但我不知道有些是什么类型的


不过,正如另一个答案所说,接口在这里也是一个很好的解决方案——这取决于应用程序的总体结构以及是否适合您的场景。

不要使用
系统。对象
对于
对象
的类型,使用您需要的实际类型(即
逻辑验证器
)。否则
dynamic
可能是你最好的选择。谢谢你的回答,你赢了我!我已经更新了我的问题。
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);  
var oAssembly = Assembly.LoadFrom(path);
var oType = oAssembly.GetType("LogicValidator");
var oObject = Activator.CreateInstance(oType);
var oInitialiseMethod = oType.GetMethod("Initialise"); //See note below the code.
var oProcessBatchMethod = oType.GetMethod("ProcessBatch"); //See note below the code.
oInitialiseMethod.Invoke(oObject, "param1", "param2", "param3", AuditTrail, UserInfo, workingDir);
Console.WriteLine("Begin processing...");
oObject.ProcessBatch(cm_uid);