2012-01-13 25 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)}); 

如果您计划重复解决一个迭代的类型该方法可能并不理想,因为反射带来了性能损失。

相关问题