我正在开发一个监控/处理数据的快速项目。基本上,这只是监视器,计划和处理器。监视器使用计划检查数据(ftp,本地,imap,pop等)并将新数据发送到处理器。它们都有接口。
我正在尝试找到一种合理的方法来使用config来配置每个监视器使用的计划/处理器。这很简单:
<monitor type="any.class.implementing.monitor">
<schedule type="any.class.implementing.schedule">
...
</schedule>
<processor type="any.class.implementing.processor" />
</monitor>
我正在努力解决的问题是配置任何旧监视器/计划/处理器的最佳方法是什么。一方面,可以实现构造函数参数或属性(给予任何语法):
<monitor type="any.class.implementing.monitor">
<args>
<arg value="..." />
</args>
<properties>
<property name="..." value=..." />
</properties>
<schedule type="any.class.implementing.schedule">
...
</schedule>
<processor type="any.class.implementing.processor" />
</monitor>
另一个解决方案是每个接口中的工厂方法,它将自定义配置作为参数:
public IMonitor Create(CustomConfigSection config);
我见过人们同时使用两者。你喜欢哪个?将配置映射到构造函数时的任何技巧?
我对DI是否能适应这种混乱局面感到有些不知所措。最后,它将是每个监视器实例的一组绑定,除了默认值,配置可能涵盖的内容似乎毫无意义。
答案 0 :(得分:0)
当我完成这样的事情时,我已经实现了IConfigurationSectionHandler
,它基本上用作工厂来解析配置,创建配置中指定类型的对象,并以某种方式返回它们数据结构(通常是列表或字典)。无论你是否使用IConfigurationSectionHandler
,我认为工厂是可行的方法,因为你将本地化代码来处理解析配置文件和在一个类中创建对象(或每个部分一个)。 / p>
我也更喜欢使用简单构造函数和属性setter / getter的类来配置构造函数中包含大量参数的类。这使工厂更容易操作并减少工厂与正在建造的类之间的耦合。
答案 1 :(得分:0)
首先,我将定义代表监视器的配置元素:
public class MonitorElement : ConfigurationElement
{
// ...whatever schema you prefer...
}
public class MonitorElementCollection : ConfigurationElementCollection
{
// ...standard implementation...
}
以及托管它们的配置部分:
public class YourSection : ConfigurationSection
{
[ConfigurationProperty("monitors")]
[ConfigurationCollection(typeof(MonitorElementCollection))]
public MonitorElementCollection Monitors
{
get { return (MonitorElementCollection) this["monitors"]; }
}
}
然后,我将定义一个代表监视器集的接口:
public interface IMonitorRepository
{
IEnumerable<Monitor> GetMonitors();
}
创建一个读取配置文件的实现:
public sealed class ConfiguredMonitorRepository : IMonitorRepository
{
private readonly string _sectionName;
public ConfiguredMonitorRepository(string sectionName)
{
_sectionName = sectionName;
}
public IEnumerable<Monitor> GetMonitors()
{
var section = (YourSection) ConfigurationManager.GetSection(_sectionName);
if(section != null)
{
foreach(var monitor in section.Monitors)
{
yield return ...create and configure monitor...
}
}
}
}
这定义了将配置转换为实际实例的位置,这只是您问题的一半。我认为你用于设置构造函数参数和属性的XML语法很好。您可以从Autofac's XML configuration system收集一些API和实现提示。
真的,你正在做的是一大堆IoC容器;你可以考虑利用其中的一个。