.config到构造函数的技巧?

时间:2008-11-05 03:03:20

标签: .net configuration interface inversion-of-control factory

我正在开发一个监控/处理数据的快速项目。基本上,这只是监视器,计划和处理器。监视器使用计划检查数据(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是否能适应这种混乱局面感到有些不知所措。最后,它将是每个监视器实例的一组绑定,除了默认值,配置可能涵盖的内容似乎毫无意义。

2 个答案:

答案 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容器;你可以考虑利用其中的一个。