1

我想開始使用統一,我尋求幫助這個特殊的問題: 我已經明白了什麼依賴注入/ unity是以及如何以編程方式執行此操作,但我不明白如何/何時使用Dependency-Attribute標記成員。團結DI靜態成員(例如,在靜態類節目)/何時成員獲取填充

class Program 
{ 
    static Program()   
    { 
     uContainer = new UnityContainer(); 
     var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
     section.Configure(uContainer); 
    } 

    private static IUnityContainer uContainer; 

    [InjectionMethod] 
    public static void InjectTrace(ITraceManager traceManager) 
    { 
     trace = traceManager; 
    } 

    [Dependency] 
    public static ITraceManager trace { get; set; }// = /*new WebTraceManager("C:\\","trace",true);//*/new EnterpriseLibaryLoggingWrapper(false); 

    static void Main(string[] args) 
    { 
     //Programmatically inject dependency 
     // TODO: Do this via attributes 
     //UnityContainer myContainer = new UnityContainer(); 
     //UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 

     //section.Containers["containerOne"].Configure(myContainer); 
     //trace = myContainer.Resolve<ITraceManager>(); 
     trace.ProgramStatus("Start"); 
     trace.ProgramStatus("End"); 
     Console.ReadLine(); 
    } 
} 

Main中以編程方式設置跟蹤屬性的未註釋部分工作正常。但是使用屬性「依賴」屬性不會被填充。 是否存在對統一容器的缺失調用? 謝謝你的幫助。

據史蒂夫的意見,我已經改變了例如,使用一個實例,而不是靜態類:

static Program() 
    { 
     uContainer = new UnityContainer(); 
     var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); 
     section.Configure(uContainer); 
     Instance = uContainer.Resolve<Program>(); 
    } 

    Program(ITraceManager traceManager) 
    { 
     trace = traceManager; 
    } 

    static readonly Program Instance; 

    //Do not use Dependency Attribute 
    //[Dependency] 
    public ITraceManager trace { get; set; }// = /*new WebTraceManager("C:\\","trace",true);//*/new EnterpriseLibaryLoggingWrapper(false); 

    static void Main(string[] args) 
    {   
     Instance.Run(); 
    } 

    void Run() 
    {    
     trace.ProgramStatus("Start"); 
     trace.ProgramStatus("End"); 
     Console.ReadLine(); 
    } 

但調用

Instance = uContainer.Resolve<Program>(); 

的時候,我收到一個異常告訴我,該程序未在容器中註冊。那是真實的,但should'nt 統一由程序代碼已知類型的程序與解析的依賴回報呢? 我在網上找到的例子總是使用構造函數注入這樣

IUnityContainer uContainer = new UnityContainer(); 
MyObject myInstance = uContainer.Resolve<MyObject>(); 

我終於找到了問題的注射構造樣本,當然構造函數必須是公開的。異常消息讓我有點困惑。

回答

7

的幾點:

  • 您目前似乎完全配置XML容器。 不要這樣做!您應該只配置在XML中構建(部署配置)後實際可能更改的依賴關係。對於剩下的,基於使用代碼的配置,因爲基於XML的配置很脆,缺乏編譯時的支持,缺乏IntelliSense支持,缺乏表現力。
  • 不要使用方法注入初始化組件。這導致Temporal Coupling。注入依賴關係的主要方式是使用構造函數注入。定義構造函數參數的所有依賴關係。所有具有依賴關係的類型都應該有一個single public constructor,它包含所有需要的依賴關係。 Unity會自動找到該構造函數,並知道如何調用該構造函數並注入依賴項。
  • 都不要使用屬性!這將你的代碼來使用,而應用程序的代碼應該是渾然不覺DI容器存在的容器。再次堅持構造函數注入。
+0

嗨史蒂文,謝謝你的建議。我根據你的提示(構造函數注入)修改了我的示例,但由於程序類未註冊,因此在嘗試使用container.resolve代替注入的tracemanager時出現異常。你能舉個例子嗎?謝謝 – user1430306

+0

「Unity會自動找到該構造函數,並知道如何調用該構造函數並注入依賴項。」就像這樣?:MyObject myInstance = uContainer.Resolve (); public MyObject(IDependency1 dep1){this.dependency1 = dep1;} – user1430306

+0

對不起,我的代碼中這是一個愚蠢的錯誤,構造函數不公開,但必須公開Unity! – user1430306