2012-01-13 24 views
16

我想創建一個類的實例,其中類有兩個具有相同參數數的構造函數。使用統一解決具有多個構造函數的實例

下面是實例:

_unityContainer.Resolve<IGradeType>(new ParameterOverride("gradeTypeStringFromXmlFile", gradeTypeStringFromXmlFile)); 

而且這裏的構造函數:

public GradeType(string gradeTypeStringFromXmlFile) 
    { 
     _gradeTypeStringFromXmlFile = gradeTypeStringFromXmlFile; 
    } 

    public GradeType(Enum.GradeType gradeType) 
    { 
     _gradeType = gradeType; 
    } 

如果我試圖做到這一點我得到一個異常說類型GradeType長度爲1的多個構造。無法消除

我可以通過一個構造函數設置屬性[InjectionConstructor],使其與一個工作,但我不能創建一個實例與其他構造函數的統一。

是否有某種方法讓多個構造函數具有相同數量的參數並仍然使用unity來創建實例?

+0

爲什麼在創建類之前不要在gradeType字符串上使用'Enum.Parse'? – jgauffin 2012-01-13 15:46:00

+0

它只是感覺像GradeType類轉換字符串的直觀設計。 – FatAlbert 2012-01-13 16:01:57

+1

對我來說這似乎是一個脆弱的解決方案,因爲任何不存在的值都會引發異常或隱藏錯誤。 – jgauffin 2012-01-13 17:54:34

回答

26

是的,可以告訴Unity它應該使用哪個構造函數,但是隻能在InjectionConstructor註冊類型時才能這樣做。如果你想使用這兩個構造函數,它會變得更加複雜,因爲你必須爲註冊命名並在解析時使用該名稱。

樣品與統一版本2.1.505建:

var continer = new UnityContainer(); 

continer.RegisterType<IGradeType, GradeType>("stringConstructor", 
    new InjectionConstructor(typeof(string))); 

continer.RegisterType<IGradeType, GradeType>("enumConstructor", 
    new InjectionConstructor(typeof(EnumGradeType))); 

IGradeType stringGradeType = continer.Resolve<IGradeType>("stringContructor" , 
    new DependencyOverride(typeof(string), "some string")); 

IGradeType enumGradeType = continer.Resolve<IGradeType>("enumConstructor", 
    new DependencyOverride(typeof(EnumGradeType), EnumGradeType.Value)); 
+0

就是我正在尋找的!謝謝 – FatAlbert 2012-01-13 16:06:24

+1

一個問題:當覆蓋依賴關係時,我們被迫在容器上顯式調用resolve?但是,顯式調用container.Resolve在您的應用程序代碼中並不壞嗎?哎呀,其實有兩個問題;-) – Legends 2015-04-16 23:22:52

0

刪除一個構造函數,並將該字符串強制轉換爲enum,反之亦然,然後使用該容器進行解析。

+0

您不能將字符串強制轉換爲枚舉。 – jgauffin 2012-01-13 15:46:31

+0

Enum.Parse - 如你所說 – Jason 2012-01-13 15:49:27

+0

xml中的字符串與enum完全不同(字符串是瑞典語)。然而,我問的是,如果可能有多個構造函數具有相同數量的參數,並且仍然使用unity來創建實例? – FatAlbert 2012-01-13 15:57:54

1

使用反射並按照Strategy Pattern的替代選項。在GradeType類

public class StringArg : ConstructorArgs 
{ 
    public string _gradeTypeStringFromXmlFile { get; set; } 

    public StringArg (string gradeTypeStringFromXmlFile) 
    { 
     this._gradeTypeStringFromXmlFile = gradeTypeStringFromXmlFile ; 
    } 
} 

public class EnumArg : ConstructorArgs 
{ 
    public Enum.GradeType _gradeType { get; set; } 

    public EnumArg (Enum.GradeType gradeType) 
    { 
     this._gradeType = gradeType ; 
    } 
} 

3)現在創建方法:

1)構造函數的論點

public abstract class ConstructorArgs 
{ 
} 

2)創建不同的具體參數類的序列創建一個基類反射需要。 ParseArguments掃描屬性的參數以及它找到的每個參數,它使用SetProperty將其值複製到GradeType的相應屬性。由於它使用的屬性名稱匹配,它保持相同的屬性名跨GradeType既和混凝土ConstructorArgs是很重要的:

 private void SetProperty(String propertyName, object value) 
     { 
      var property = this.GetType().GetProperty(propertyName); 
      if (property != null) 
       property.SetValue(this, value); 
     } 
     private void ParseArguments(ConstructorArgs args) 
     { 
      var properties = args.GetType().GetProperties(); 
      foreach (PropertyInfo propertyInfo in properties) 
      { 
       this.SetProperty(propertyInfo.Name, 
        args.GetType().GetProperty(propertyInfo.Name).GetValue(args)); 
      } 
     } 

4)在您的GradeType類中創建相應的屬性(記住,你必須正是使用在混凝土ConstructorArgs使用相同的名稱和類型,但你可以用你喜歡的任何訪問修飾符)

public string _gradeTypeStringFromXmlFile { get; set; } 
    public Enum.GradeType _gradeType { get; set; } 

5)創建一個構造你的GradeType類類型ConstructorArgs的參數:

public GradeType(ConstructorArgs args) 
    { 
     this.ParseArguments(args); 
    } 

6)現在,你可以註冊使用一個構造函數在Unity GradeType,但你可以在不同類型作爲參數解析時,它傳遞:

_unityContainer.RegisterType<IGradeType, GradeType>(
     new InjectionConstructor(typeof(ConstructorArgs))); 

    var args1 = new StringArg(gradeTypeStringFromXmlFile); // string 
    IGradeType gradeType1 = _unityContainer.Resolve<IGradeType>(
     new ResolverOverride[]{new ParameterOverride("args", args1)}); 

    var args2 = new EnumArg(gradeType); // enum 
    IGradeType gradeType2 = _unityContainer.Resolve<IGradeType>(
     new ResolverOverride[]{new ParameterOverride("args", args2)}); 

如果您計劃重複解決一個迭代的類型該方法可能並不理想,因爲反射帶來了性能損失。

相關問題