必须在某处输入新信息,这是不可避免的;关键是将其从代码中删除,以避免因如此微不足道的更改而重新编译和重新部署。
一些不错的选择是在 XML 配置文件中列出这些值,或者更好的是在数据库中列出这些值。
您可能希望用这些数据填写一本字典,无论其来源如何。这会:
当需要将数据从配置中提取到代码中时,您可以将项目添加到字典中,如下所示:
Dictionary<string, IReportCreator> = configDataGetter.GetReportDataFromDB().
ToDictionary(r => r.Name, myReportCreatorFactory(r => r.ReportID))
此示例假设您将数据作为某种实体对象获取,并使用一个工厂,该工厂将使用策略模式 http://en.wikipedia.org/wiki/Strategy_pattern用于创建报告的代码。当然,有无数种方法可以做到这一点。
我认为这些报告过于广泛、多样且性质不同,以至于您不能只将 sql 和样式构建块放入数据库中?
Edit根据op的评论:
啊,明白了。好吧,我不知道你有多少时间,但只要你把一切都投入到某种形式中factory http://en.wikipedia.org/wiki/Factory_method_pattern,您稍后会有更好的选择。我将从我做过的类似事情中给你一些想法,希望对你有所帮助。每个步骤本身都是一个改进,但也是真正将报告逻辑与此 shell 代码分离的一小步。此外,我可以看到你已经知道你在做什么,我确信知道我下面要说的一些内容,但我不知道你知道什么,这对其他人会有帮助。
首先,将代码中的所有信息提取到数据库(如果还没有),然后在改进设置时添加更多数据库字段(以及一两个表)。
您可能已经知道了,但我会向其他人提及它,以查看我上面引用的策略模式。您可以让每个“报告函数”的自定义逻辑实际上位于各种策略类的构造函数中。它们都将从您的基础 ReportGenerator 继承(或使用通用的 IReportGenerator 接口)。他们可以而且应该共享相同的构造函数;不同的报告参数将由字典类型的参数处理。每个类的构造函数实现都会知道需要的变量类型(来自数据库配置),并相应地转换/使用它们。
下一步可能是真正摆脱工厂中的 select 语句,使用反射 http://www.codeproject.com/Articles/17269/Reflection-in-C-Tutorial。您必须将类的名称作为数据库中报告配置数据的一部分(并且具有公共构造函数)。
此时,添加新报告的方法非常干净,即使您每次都必须添加一个新类。那么好。它满足了单一职责 http://en.wikipedia.org/wiki/Single_responsibility_principle and 打开关闭 http://en.wikipedia.org/wiki/Open/closed_principle校长。
现在,只剩下最后一步了从您的应用程序中删除类,因此可以即时添加/编辑它们。查看MEF http://managed%20extensibility%20framework。这就是它的用途。您可能会在互联网上找到一些您可能会发现的东西不应该使用是CodeDom http://msdn.microsoft.com/en-us/library/y2k85ax6.aspx(在没有其他东西的情况下很棒,但 MEF 更好)以及 .NET 5 中的编译即服务功能。MEF 是最佳选择。