3

Sometimes, I have really complex models with many string properties that need to be validated on setting, however the validation doesn't often go further than IsNotNullOrWhitespace.

This often leads to unnecessary code repetition, so I wondered if there's a way to automatically validate property setter values, preferably without any additional framework.

Possible Solutions

  • AOP (e.g. with PostSharp)
  • Fluent validation
  • Data Annotations

Data Annotations feels as the most natural way to me, as the validation is very close to the model and since it's part of the .Net-Framework, attributes are okay. However, if I'm using the model outside of MVC or serialization, I have to do the validation manually using a validator. So I have to do the validation probably at many places (repositories, APIs, services) and if I forget about doing this somewhere, my domain rules can be broken.

AOP might be the perfect way, however there isn't such a thing directly in C# and tightly coupling my domain models to a infrastructure component like PostSharp or Ninject (interception) is a no-no.

Acrotygma
  • 2,531
  • 3
  • 27
  • 54
  • 1
    When does validation need to take place? When @ setter, yes, you should use AOP. You could look into Fody (https://github.com/Fody/Fody) which is free.. maybe this diminishes your concern about coupling to infrastructure components. Anyway i got to ask: Would you rather have more code and pay for it and it's maintenance over and over again, or would you rather depend on an infrastructure component, speeds up development and reduces chance of bugs? What's an infrastructure component and what isn't? Do you rely on VS or do you use an (any) text editor since coupling bothers you too much? ;-) – BatteryBackupUnit May 22 '14 at 05:34

1 Answers1

1

Try NConcern AOP Framework

This new minimal runtime AOP framework (on which I actively work) can help you to manage validation by AOP without coupling your domain assembly.

Into your validation assembly, define your own validation attribute and how to validate it.

The custom attribute to define/identify an email

[AttributeUsage(AttributeTargets.Property)]
public class Email : Attribute
{
    //validation method to use for email checking
    static public void Validate(string value)
    {
        //if value is not a valid email, throw an exception!
    }
}

Validation aspect to check code contract

//Validation aspect handle all my validation custom attribute (here only email)
public class EmailValidation : IAspect
{
    public IEnumerable<IAdvice> Advise(MethodInfo method)
    {
        yield return Advice.Before((instance, arguments) =>
        {
            foreach (var argument in arguments)
            {
                if (argument == null) { continue; }
                Email.Validate(argument.ToString());
            }
        });
    }
}

Your domain assembly

public class Customer
{
    [Email]
    public string Login { get; set; }
}

Into another assembly (link between validation and domain

//attach validation to Customer class.
foreach (var property in typeof(Customer).GetProperties())
{
    if (property.IsDefined(typeof(Email), true))
    {
        Aspect.Weave<Validation>(property.GetSetMethod(true));
    }
}
Tony THONG
  • 772
  • 5
  • 11