[英]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.