[英]Register all class that implements IValidator<SomethingValidatable> with 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>
的給定名稱空間中注冊每個類 。
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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.