我已经看到了一些可能对我有帮助的例子,但是我没有那么多时间来探索它们,因为我今天发现我的老板必须比计划提前一周进行演示,并且我想添加这个新功能。我会尽量保持这种简短和甜蜜。
好的,这就像我第10次尝试纠正这一点,希望它是明确的。这是一个应用程序。需要在DataGridView(已完成)中显示数据行。根据报告(完成),某些行的突出显示不同。大多数报告都有自己的SQL文件,并在运行时从INI文件(完成)实现。但是,有些报告需要调用函数。该应用程序正在使用SQLite数据库。我想拥有作为报告的DLL,所有格式相同,并且所有这些都返回ReportRecord列表。 ReportRecord是在我的主应用程序中定义的类,但我也会在创建它们时在每个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岁)的例子,否则它将无法回答。
答案 0 :(得分: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");
}
答案 1 :(得分:1)
不要以DLL为原始文件来看待这个,而是使用Assemblies,这就是.NET看待事物的方式。您可以使用Assembly.Load
加载程序集。话虽如此,您是否考虑过更通用的解决方案,例如inversion of control?
答案 2 :(得分:1)
我真的不明白你到底要做什么,而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);
答案 3 :(得分:0)
考虑使用插件架构(例如Managed Extensibility Framework)来管理报告模块。
答案 4 :(得分:0)
您可能需要考虑使用Managed Extensibility Framework。它使这种类型的操作变得微不足道。
您可以在上面下载.NET 3.5(它已经在.NET 4的框架中了)。通过使用MEF,您只需通过DirectoryCatalog一次性导入所有导出的“报告”的集合,它将为您处理所有接线。
有关详细信息,请参阅Importing Collections here上的帮助。