簡體   English   中英

注冊實現IValidator的所有類 <SomethingValidatable> 與Unity

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM