Validation for DTO using DataAnnotations
What do you think about non static validators? While making validators smarter, we will sooner or later need to wire up their dependencies (like repositories)... Validators can easily do much more while being instantiated by IoC container.

I would suggest to define this interface and class:

interface IModelValidator&lt;in T&gt;
{
    IEnumerable&lt;string&gt; Validate(T subject);
}

class ModelValidator&lt;T&gt; : IModelValidator&lt;T&gt;
{
    public ModelValidator(IEnumerable&lt;IModelValidator&lt;T&gt;&gt; validators)
    {
        Validators = validators;
    }

    public IEnumerable&lt;string&gt; Validate(T subject) =&gt;
        Validators.SelectMany(v =&gt; v.Validate(subject));

    IEnumerable&lt;IModelValidator&lt;T&gt;&gt; Validators { get; }
}


Now some demo code; models:

class Order { }
class MailOrder : Order { }


Validators:

class OrderValidator : IModelValidator&lt;Order&gt;
{
    public IEnumerable&lt;string&gt; Validate(Order subject)
    {
        yield return "Bad order.";
    }
}

class MailOrderValidator : IModelValidator&lt;MailOrder&gt;
{
    public IEnumerable&lt;string&gt; Validate(MailOrder subject)
    {
        yield return "Bad mail order.";
    }
}


Something to check validity of the order:

class Controller
{
    public Controller(ModelValidator&lt;MailOrder&gt; validator)
    {
        var order = new MailOrder();
        foreach (var message in validator.Validate(order))
            Console.WriteLine(message);
    }
}


So now it is just about proper registering them in IoC container (here Autofac):

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        builder.RegisterSource(new ContravariantRegistrationSource());
        builder.RegisterGeneric(typeof(ModelValidator&lt;&gt;))
            .AsSelf();
        builder.RegisterType&lt;OrderValidator&gt;()
            .AsImplementedInterfaces();
        builder.RegisterType&lt;MailOrderValidator&gt;()
            .AsImplementedInterfaces();
        builder.RegisterType&lt;Controller&gt;()
            .AsSelf();

        IContainer container = builder.Build();
        var controller = container.Resolve&lt;Controller&gt;();
    }
}


You could play with it to discover how perfectly contravarians works here. You just declare what to validate - compatible validators will show up. No need to change client code - just register more validators if necessary. One of them might be IModelValidator&lt;DtoBase&gt; with attribute checking.