2016-05-31 12 views
0

でIValidator を実装して、すべてのクラスが、私はこのようないくつかの検証ロジック定義されたと仮定します。私は、1つまたは複数の具体的な RuleIValidator<SomethingValidatable>をバインド 登録ユニティ

どこかのコードで
public class Rule1 : IValidator<SomethingValidatable> 
{ 
    public IList<Error> Validate(SomethingValidatable item) 
    { 
     // apply validation logic to item 
    } 
} 

を:

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; 
    } 
} 

これは仕事をします。しかし、私は明示的にそれぞれのルールを1つずつ登録することを避けるでしょう。私は本当に言う:親愛なる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(); 
} 

それは関係なく、Tの、IValidator各実装を登録します

関連する問題