2016-05-31 22 views
0

假设我定义一些验证逻辑是这样的:注册所有类,它实现IValidator <SomethingValidatable>使用Unity

public class Rule1 : IValidator<SomethingValidatable> 
{ 
    public IList<Error> Validate(SomethingValidatable item) 
    { 
     // apply validation logic to item 
    } 
} 

某处在代码我结合IValidator<SomethingValidatable>到一个或多个具体Rule

protected override void ConfigureContainer(IUnityContainer container) 
{ 
    container 
     .RegisterType<IValidator<SomethingValidatable>, Rule1>("a") 
     .RegisterType<IValidator<SomethingValidatable>, Rule2>("b"); 
} 

并在我需要这种验证发生我有事端喜欢:

public class HereIValidateClass 
{ 
    private readonly IValidator<SomethingValidatable>[] validators; 

    public HereIValidateClass(IValidator<SomethingValidatable>[] validators) 
    { 
     this.validators = validators; 
    } 

    public IList<Error> DoSomething() 
    { 
     foreach (var validator in validators) 
     { 
      var errors = validator.Validate(something); 
      // append to IList<Error> 
     } 

     return errors; 
    } 
} 

这样做的工作。但我会避免每个规则逐一注册。我真的很想说:尊敬的Unity,注册每个类在一个给定的命名空间,实现IValidator<SomethingValidatable>

+0

看看这个[SO Answer](http://stackoverflow.com/a/27372032/1504480)。这是关于按照惯例注册的。 –

回答

0

怎么样在IUnityContainer扩展方法:

public static class UnityExtensions 
{ 
    public static void RegisterValidators(this IUnityContainer container) 
    { 
     var types = AllClasses.FromLoadedAssemblies().GetValidators(); 
     foreach (var type in types) 
     { 
      var interfaces = WithMappings.FromAllInterfaces(type); 
      foreach (var @interface in interfaces) 
      { 
       container.RegisterType(@interface, type); 
      } 
     } 
    } 

    public static IEnumerable<Type> GetValidators(this IEnumerable<Type> types) 
    { 
     var wantedType = typeof(IValidator<>); 
     return from type in types 
       from interfaceType in type.GetInterfaces() 
       where interfaceType.IsGenericType 
        && !interfaceType.ContainsGenericParameters 
        && wantedType.IsAssignableFrom(interfaceType.GetGenericTypeDefinition()) 
       select type; 
    } 
} 

如果您需要了解具体的注册的详细信息,您可以使用一个属性。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] 
public class MyValidationAttribute : Attribute 
{ 
    public string RegistrationName { get; set; } 

    public MyValidationAttribute(string name) 
    { 
     RegistrationName = name; 
    } 
} 

,然后更改扩展方法是这样的:

public static void RegisterValidators(this IUnityContainer container) 
    { 
     var types = AllClasses.FromLoadedAssemblies().GetValidators(); 
     foreach (var type in types) 
     { 
      var interfaces = WithMappings.FromAllInterfaces(type); 
      foreach (var @interface in interfaces) 
      { 
       var myAttr = type.GetCustomAttributes<MyValidationAttribute>(false); 
       foreach (var attr in myAttr) 
       { 
        // Register with specific name. 
        container.RegisterType(@interface, type, attr.RegistrationName); 
       } 
      } 
     } 
    } 

和更改您的注册:

protected override void ConfigureContainer(IUnityContainer container) 
{ 
    container.RegisterValidators(); 
} 

将注册每个实施IValidator,无论T.