2011-10-04 48 views
8

好方式,我正在做我涉足這個奇妙的網站有大約注入配置設置應用程序組件的正確方法問題。所以,概述是:我有一個用C#.Net 3.5編寫的應用程序。它由3個組件組成 - 一個核心,一個數據和一個服務。數據&服務組件需要從在app.config,其經由設置文件,例如進行檢索設置。最佳注入應用程序配置

代碼:

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

配置:

<applicationSettings> 
    <MyNamespace.Data.ConnectionSettings> 
    <setting name="RequestQueueConnectionString" serializeAs="String"> 
    ... 

現在,組件是用StructureMap的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<DataConfig>() 
           .Singleton() 
           .Use ??? 
    ... 

我希望我在這裏提供足夠的細節 - 原諒一個新手,如果我沒有,請讓我知道什麼是在回答這是很有幫助的!

+1

你可能想看看[這個問題](http://stackoverflow.com/q/7288859/644812)。 –

回答

3

所以,很多搜索和反覆試驗後,我提交了@ default.kramer的鏈接,這是我duely跟着!再次嘗試一下(我認爲最好的方式),我設法找到了我所需要的解決方案。現在,雖然你可以按照鏈接(我會強烈建議這樣做),我要解決張貼到我的問題,因爲我實現了它。希望這可以幫助有類似問題的人。

所以,我現在有我的配置設置類,像這樣:

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

然後在現實世界中,我能夠從應用程序獲取設置。配置:

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

最後,配置文件長相像這樣:

<?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> 

現在,任何敏銳的眼睛都會發現「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; 
     } 
    } 
} 

那裏你有它!我希望這可以讓任何遇到類似問題的人解決問題,並且足夠清楚地遵循!

相關問題