2012-06-06 40 views
2

時,這是一個示例控制檯應用程序(它會運行加入統一金塊包後細調)似乎表明在Unity了一個錯誤:UnityContainer.RegisterType不習慣於放在一個靜態構造函數

using System; 
using Microsoft.Practices.Unity; 

class GC { public static UnityContainer Container = new UnityContainer();} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     GC.Container.RegisterType<MyView>(); 
     var myView = GC.Container.Resolve<MyView>(); 
     Console.ReadLine(); 
    } 
} 

public class MyClassDesign: MyClass{} 
public class MyClass: VMBase<MyClass, MyClassDesign>{} 
public abstract class VMBase<TViewModel, TDesignVM> where TDesignVM:TViewModel 
{ 
    static VMBase() 
    { 
     if (!GC.Container.IsRegistered(typeof(TViewModel))) 
      GC.Container.RegisterType(typeof (TViewModel), typeof(TDesignVM)); 
    } 
} 

public class MyView 
{ 
    public MyView(MyClass myClass) 
    { 
     Console.WriteLine("Bad: "+myClass.GetType().ToString()); 
     Console.WriteLine("Good: "+GC.Container.Resolve<MyClass>().GetType()); 
    } 
} 

輸出是:

壞:MyClass的
好:MyClassDesign

解決的類型是MyClass。但它應該是MyClassDesign。 (靜態構造函數運行在MyView類被解決之前MyClass的。)

我怎樣才能得到統一,讓我建立我的映射在靜態構造函數?

注意:當我更改此設置UnityContainer與文件(而不是在代碼中)它一切正常。但我寧願不依賴外部文件。 (我正在製作一個可重複使用的模板,我不希望依賴太多)

回答

0

爲什麼要將註冊邏輯放入視圖模型中?這將您的應用程序代碼耦合到容器,這絕不是一個好主意。看看Composition roots的概念。

DI容器的所有設置代碼都應放置在那裏。

0

這不是Unity的一個錯誤。問題在於靜態ctor在請求實例之前不會運行(在這一點上unity仍然不知道MyClassDesign)。這意味着Unity已經開始創建MyClass的實例來完成請求。隨後對GC.Container.Resolve<MyView>();的任何調用都將產生您期望的輸出。正如Sebastian Weber所建議的,將所有設置代碼放在一個完全獨立的位置(這樣您的課程不依賴於特定的DI容器)是最好的選擇。