[英]C#: How do I dynamically load/instantiate a DLL?
我已经看到了一些可能对我有帮助的示例,但是我没有太多的时间去探索它们,因为我今天发现我的老板们必须比原计划提前一周进行演示,我想添加此新功能。 我会尽量保持简短和甜美。
好的,这就像我第十次尝试纠正此问题以使其更清晰,希望是的。 这是一个应用程序。 数据行需要在DataGridView中显示(完成)。 根据报告(完成),某些行以不同的方式突出显示。 大多数报告都有自己的SQL文件,并在运行时从INI文件实现(完成)。 但是,某些报告需要调用功能。 该应用程序正在使用SQLite数据库。 我想拥有作为报告的DLL,它们都具有相同的格式,并且它们都返回ReportRecord的列表。 ReportRecord是在我的主应用程序中定义的类,但是在创建每个DLL时,我也会在每个DLL中定义它。 我想实例化DLL,将其称为“ GetRecords”函数,然后在我的主应用程序中使用它。 这是一些伪代码。 如果你们可以告诉我是否可行,或者给我一个更好的方法的想法,我将不胜感激。
伪码
foreach (string str in System.IO.Directory.GetFiles("C:\\ReportDlls", "*.dll"))
{
//Instantiate DLL e.g. newReport
//_lstReportRecords.AddRange(newReport.GetReportRecords());
}
反正有这样做吗?
目前,在找到答案之前,我需要补充以下内容:
private void RefreshReports(string strReportTitle)
{
_lstReportRecords = _lstReportRecords.Where(rr => rr.Description != strReportTitle).ToList<ReportRecord>();
string strColumn = iniFile.GetString(strReportTitle, "Column", "");
if (strColumn != null)
{
_lstReportRecords.AddRange(_dataController.BuildReportList(strColumn, strReportTitle, GetReportSQL(strReportTitle)));
}
else
{
switch (strReportTitle)
{
case "Improper Indenture":
_lstReportRecords.AddRange(_dataController.ImproperIndenture());
break;
case "Skipping Figure":
_lstReportRecords.AddRange(_dataController.SkippingFigure());
break;
default: break;
}
}
FormatCells();
}
感谢大家。
编辑 :对不起,老兄,看着这些东西真让我感到愚蠢。 就像,我的脑子一片空白,全神贯注。 :)你们提供的可能是最好的方法,但是由于我必须在星期二之前准备好质量的演示,并且在那之前不应再添加任何需要功能的报告,因此我将保持这种状态。 我的老板出门演示后,我将继续实施。 但是现在,除非我看到一个非常非常(针对2岁儿童)的例子,否则它将无法解决。
您可以简单地创建一个实现以下接口的C#库项目,然后将二进制文件存储在数据库或文件系统中。 然后,您可以从原始程序集字节/文件路径加载程序集,以实例化对象。 通过反射,您还可以直接调用构造函数,但是我更喜欢将工厂模式用于此类任务。
public interface IReportModule
{
}
public interface IReportModuleFactory
{
IReportModule Create();
}
private static IReportModule CreateReportModuleFromRawAssemby(byte[] rawAssembly)
{
var reportModule = Assembly.Load(rawAssembly);
var factoryType = reportModule.GetExportedTypes()
.FirstOrDefault(x => x.IsAssignableFrom(typeof(IReportModuleFactory)));
if (factoryType != null)
{
var reportModuleFactory = (IReportModuleFactory)
reportModule.CreateInstance(factoryType.FullName);
return reportModuleFactory.Create();
}
else
throw new NotImplementedException("rawAssembly does not implement IReportModuleFactory");
}
不要以DLL(原始文件)的角度来看问题,而要用Assemblies(.NET看到事物的样子)的观点来看。 您可以使用Assembly.Load
加载程序Assembly.Load
。 话虽如此,您是否考虑过更通用的解决方案,例如控制反转 ?
我不太了解您到底想做什么,IOC可能是您的选择。 但是据我了解,您可以通过纯粹的反思来做到这一点。
提醒您,这远非理想的方法,但您正在要求它:)
它就到了(我的头顶,所以如果有任何问题请不要向我开枪,它应该很近,尽管不是万无一失的)
// load assembly
var assemblyWithReport = Assembly.LoadFrom("Path of your assembly");
// or another Loadxx to get the assembly you'd
// like, whether it's referenced or not
// load type
var reportType = assemblyWithReport.GetTypes().ToList()
.Where(t => t.Name == "ReportRecord").Single();
// create instance of type
var instance = Activator.CreateInstanceOf(reportType);
// get getrecords method of the type
var getRecordsMethod = reportType.GetMethod("GetRecords");
// invoke getrecords method on the instance
object result = getRecordsMethod.Invoke(instance, null);
考虑一个用于管理报表模块的插件体系结构,例如Managed Extensibility Framework 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.