且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

注入应用程序配置的***方式

更新时间:2023-09-21 09:27:52

所以,经过大量的搜索和尝试和错误,我被提出了@ default.kramer的链接,我一直追随!有一点点试验和错误,再次(在我看来***的方式),我设法得到我寻找的解决方案。现在,虽然你可以跟随链接(我强烈建议这样做),我将post的解决方案我的问题,因为我实现它。希望这可能会帮助有类似问题的人。

So, after a lot of searching and trial and error, I was presented with @default.kramer's link, which I duely followed! With a little bit of trial and error, again (best way in my opinion), I managed to get the solution I was looking for. Now, whilst you can follow the link (and I would highly suggest doing so), I am going to post the solution to my question as I implemented it. Hopefully this might help someone with a similar problem.

所以,现在我的配置设置类如下:

So, I now have my configuration setup class like so :

public static class DispatchConfiguration
{
    public static void ConfigureStructureMap(IContainer container, IDispatchConfiguration dispatchConfig)
    {
        DispatchProcessBatchSize = dispatchConfig.DispatchProcessBatchSize;
        ServiceIsActive = dispatchConfig.ServiceIsActive;
        ...
    }

现在,在使用设置文件以从app.config文件中检索配置。这显然是很好地确保我有灵活性,在更改我的配置设置,但它留给我的问题,无法轻松测试这些设置。说9-10测试需要服务是活跃的,但1测试想测试ServiceIsActive = false;,现在我有麻烦。

Now, before I was using a settings file to retrieve the configuration out of the app.config file. This was obviously good for ensuring I had flexibility in changing my config settings, but it left me with the problem of not being able to easily test those settings. Say 9/10 tests required the service to be active, but 1 test wanted to test "ServiceIsActive = false;", now I'm in trouble.

现在,我可以通过测试注入配置:

Now, however, I am able to inject the configuration from the test :

[Given(@"Config\.IsServiceActive returns false")]
public void GivenConfig_IsServiceActiveReturnsFalse()
{
    var settings = new DispatchSettings
    {
        ServiceIsActive = false,
        DispatchProcessBatchSize = 100,
        UpdatedBy = "Unit Test"    
    };

    DispatchConfiguration.ConfigureStructureMap(ObjectFactory.Container, settings);
}

然后在现实世界中,我可以从应用程序获取设置。 config:

And then in the real world I am able to get the settings from app.config :

public void Start(String[] args)
{
    var dispatchConfig = this.GetDispatchConfiguration();
    DispatchConfiguration.ConfigureStructureMap(ObjectFactory.Container, dispatchConfig);
    ...
}

private IDispatchConfiguration GetDispatchConfiguration()
{
    var config = (DispatchSettings)ConfigurationManager.GetSection("DispatchSettings");
    return config;
}

然后实际的配置类如下:

And then the actual config class looks like :

[XmlRoot(ElementName = "DispatchSettings", Namespace = "")]
public sealed class DispatchSettings : IDispatchConfiguration
{
    public Int32 DispatchProcessBatchSize { get; set; }
    public Boolean ServiceIsActive { get; set; }
    ...
}

为了完整起见,像这样:

For the sake of completeness the interface looks like so :

public interface IDispatchConfiguration
{
    Int32 DispatchProcessBatchSize { get; }
    Boolean ServiceIsActive { get; }
    ...
}

最后,配置文件看起来像this:

And finally, the config file looks like this :

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <section name="DispatchSettings" type="MyNamespace.XmlConfigurator, MyNamespace.Core" />
    </configSections>

    <DispatchSettings type="MyNamespace.DispatchSettings, MyNamespace.Core">
        <ServiceIsActive>True</ServiceIsActive>
        <DispatchProcessBatchSize>100</DispatchProcessBatchSize>
    </DispatchSettings>

eye会发现MyNamespace.XmlConfigurator。我在我的一个Google旅程中发现了这个,并且代码允许你反序列化一个Xml配置到你想要的类中(如这个例子所示)。所以,为了确保你有完整的代码,使这项技术工作,下面是XmlConfigurator的代码。我不记得我在哪里碰到它了,但是非常感谢编写它的人。

Now, anyone with a keen eye will spot "MyNamespace.XmlConfigurator". I found this on one of my Google journeys, and the code allows you to deserialize an Xml config into a class of your desire (as shown in this example). So, to ensure you have the complete code to make this technique work, below is the code for the XmlConfigurator. I cannot remember where I came across it, but a big thanks to the person who wrote it!!

public sealed class XmlConfigurator : IConfigurationSectionHandler
{
    public XmlConfigurator()
    {
    }

    public object Create(object parent, object configContext, XmlNode section)
    {
        XPathNavigator navigator = null;
        String typeName = null;
        Type sectionType = null;
        XmlSerializer xs = null;
        XmlNodeReader reader = null;

        try
        {
            Object settings = null;

            if (section == null)
            {
                return settings;
            }

            navigator = section.CreateNavigator();
            typeName = (string)navigator.Evaluate("string(@type)");
            sectionType = Type.GetType(typeName);
            xs = new XmlSerializer(sectionType);
            reader = new XmlNodeReader(section);

            settings = xs.Deserialize(reader);

            return settings;
        }
        finally
        {
            xs = null;
        }
    }
}

我希望这允许任何具有类似问题的人解决它,并且足够清楚跟随!

And there you have it! I hope this allows anyone with a similiar issue to resolve it and is clear enough to follow!