【问题标题】:.config to constructor tricks? [closed].config 到构造函数的技巧? [关闭]
【发布时间】:2010-09-20 19:47:27
【问题描述】:

我正在做一个快速的项目来监控/处理数据。本质上,这只是监视器、时间表和处理器。监视器使用计划检查数据(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 是否能融入这个烂摊子,我有点担心。最后,这将是每个监视器实例的一组绑定,除了默认值之外,这似乎毫无意义,配置可以覆盖。

【问题讨论】:

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


    【解决方案1】:

    首先,我将定义代表监视器的配置元素:

    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 容器的强项;您可以考虑利用其中之一。

    【讨论】:

      【解决方案2】:

      当我做完这类事情后,我实现了一个IConfigurationSectionHandler,它基本上作为一个工厂来解析配置,创建配置中指定类型的对象,并以某种数据返回它们结构(通常是列表或字典)。无论您是否使用IConfigurationSectionHandler,我认为工厂都是可行的方法,因为您将本地化处理解析配置文件并在一个类(或每个部分一个)中创建对象的代码。

      我也更喜欢具有简单构造函数和属性设置器/获取器的类,而不是构造函数中具有大量参数的类。这使得工厂更容易操作,减少了工厂与正在构建的类之间的耦合。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-26
        • 2019-01-09
        • 2011-05-25
        • 2010-12-14
        相关资源
        最近更新 更多