注入应用程序配置的最佳方式

好吧,我正在进入这个梦幻般的网站,并提出了将配置设置注入应用程序组件的正确方法的问题。 因此,概述是:我有一个用C#.Net 3.5编写的应用程序。 它由3个程序集组成 – 核心,数据和服务。 数据和服务程序集需要从app.config检索的设置,这可以通过设置文件完成,例如。

代码:

public static String RequestQueueConnectionString { get { return ConnectionSettings.Default.RequestQueueConnectionString; } } 

配置:

    ... 

现在,程序集都是使用StructureMap for IoC设置的 – 我认为应该提供我正在寻找的答案,但我只是看不到它!

IoC:

 public static void ConfigureStructureMap(IContainer container) { container.Configure(x => ... ... 

我想要做的是注入已填充到IoC容器中的配置类,以便这些设置用于该程序集,而不是设置文件/ app.config中指定的那些。 所以也许:

 public static void ConfigureStructureMap(IContainer container, MyConfigClass config) { container.Configure(x => x.For() .Singleton() .Use ??? ... 

我希望我在这里提供了足够的细节 – 如果我没有,请原谅一个新手,请让我知道还有什么有助于回答这个问题!

因此,经过大量的搜索和反复试验后,我收到了@ default.kramer的链接,我应该遵循这个链接! 经过一点点的反复试验(我认为最好的方式),我设法得到了我想要的解决方案。 现在,虽然您可以按照链接(我强烈建议这样做),但我将在实施时将解决方案发布到我的问题中。 希望这可能会帮助有类似问题的人。

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

 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;”,现在我遇到了麻烦。

但是,现在,我可以从测试中注入配置:

 [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); } 

然后在现实世界中,我可以从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; } 

然后实际的配置类看起来像:

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

为了完整起见,界面看起来像这样:

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

最后,配置文件如下所示:

    
True 100

现在,任何有敏锐眼光的人都会发现“MyNamespace.XmlConfigurator”。 我在我的一个Google旅程中找到了这个,并且代码允许您将Xml配置反序列化为您想要的类(如本例所示)。 因此,为确保您拥有使此技术有效的完整代码,下面是XmlConfigurator的代码。 我不记得我遇到过哪里,但非常感谢写这篇文章的人!

 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; } } } 

你有它! 我希望这允许任何有类似问题的人解决它并且足够明确可以遵循!