2016-05-31 65 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.