2011-10-04 31 views
8

Vâng, tôi đang bước đột phá vào trang web tuyệt vời này với một câu hỏi về cách chính xác để chèn các cài đặt cấu hình vào các thành phần ứng dụng. Vì vậy, tổng quan là: Tôi có một ứng dụng được viết bằng C# .Net 3.5. Nó bao gồm 3 hội đồng - một lõi, một dữ liệu và một dịch vụ. Dữ liệu & cụm dịch vụ yêu cầu cài đặt được truy xuất từ ​​app.config, được thực hiện thông qua tệp cài đặt, ví dụ:Cách tốt nhất để tiêm cấu hình ứng dụng

Code:

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

Config:

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

Bây giờ, các hội đồng đều thiết lập sử dụng StructureMap cho IoC - để tâm trí của tôi nên cung cấp câu trả lời cho những gì tôi đang tìm kiếm, nhưng Tôi chỉ không thể nhìn thấy nó!

IoC:

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

Những gì tôi muốn để có thể làm là để tiêm một lớp cấu hình sẵn có ở đó vào container IoC như vậy mà những thiết lập được sử dụng để lắp ráp đó, chứ không phải những quy định trong tập tin cài đặt/app.config. Vì vậy, có lẽ:

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

Tôi hy vọng tôi đã cung cấp đủ chi tiết ở đây - tha thứ cho một newbie nếu tôi không và vui lòng cho tôi biết điều gì khác hữu ích khi trả lời câu hỏi này!

+1

Bạn có thể xem [câu hỏi này] (http://stackoverflow.com/q/7288859/644812). –

Trả lời

3

Vì vậy, sau rất nhiều tìm kiếm và thử nghiệm và lỗi, tôi đã được giới thiệu với liên kết @ default.kramer, mà tôi đã theo dõi! Với một chút thử thách và lỗi, một lần nữa (cách tốt nhất theo ý kiến ​​của tôi), tôi đã xoay xở để có được giải pháp mà tôi đang tìm kiếm. Bây giờ, trong khi bạn có thể làm theo các liên kết (và tôi rất muốn đề nghị làm như vậy), tôi sẽ đăng các giải pháp cho câu hỏi của tôi khi tôi thực hiện nó. Hy vọng rằng điều này có thể giúp ai đó với một vấn đề tương tự.

Vì vậy, tôi bây giờ có lớp thiết lập cấu hình của tôi như vậy:

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

Bây giờ, trước khi tôi đã sử dụng một tập tin cài đặt để lấy cấu hình ra khỏi file app.config. Điều này rõ ràng là tốt để đảm bảo tôi đã linh hoạt trong việc thay đổi các thiết lập cấu hình của tôi, nhưng nó lại cho tôi với vấn đề không thể dễ dàng kiểm tra các thiết lập đó. Nói 9/10 kiểm tra yêu cầu dịch vụ phải hoạt động, nhưng 1 thử nghiệm muốn kiểm tra "ServiceIsActive = false;", bây giờ tôi đang gặp rắc rối.

Bây giờ, tuy nhiên, tôi có thể tiêm các cấu hình từ thử nghiệm:

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

Và sau đó trong thế giới thực tôi có thể có được các thiết lập từ ứng dụng.cấu hình:

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

Và sau đó các lớp cấu hình thực tế trông giống như:

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

Vì lợi ích của sự hoàn chỉnh giao diện trông giống như vậy:

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

Và cuối cùng, các tập tin cấu hình ngoại hình như thế này:

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

Bây giờ, bất kỳ ai có con mắt sắc bén đều sẽ phát hiện ra "MyNamespace.XmlConfigurator". Tôi tìm thấy điều này trên một trong những hành trình của Google và mã cho phép bạn deserialize một cấu hình Xml thành một lớp mong muốn của bạn (như trong ví dụ này). Vì vậy, để đảm bảo bạn có mã hoàn chỉnh để làm cho kỹ thuật này hoạt động, bên dưới là mã cho XmlConfigurator. Tôi không thể nhớ nơi tôi bắt gặp nó, nhưng một lời cảm ơn lớn đến người đã viết nó !!

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

Và ở đó bạn đã có! Tôi hy vọng điều này cho phép bất cứ ai có một vấn đề tương tự để giải quyết nó và rõ ràng là đủ để làm theo!

Các vấn đề liên quan