Monthly Archives: March 2012
Announcing Simple.Validation

My company has graciously allowed me to develop a lightweight validation framework and publish it as open-source. There are other very nice validation frameworks available, so why another one? I wanted to be able to use something with all of the strengths and none of the weaknesses of the existing libraries. Here are my stated goals for the project:

  • Simplicity
  • Get moving with a minimum number of moving parts
  • Support dependency injection
  • Focus on object-level validation
  • Support for common property-level validation
  • Support all application types in a consistent manner
  • Support validation at all application layers in a consistent manner
  • Pluggable Architecture

The api I wanted for usage was very simple. Here’s some code from the LoanApplicationSample project:

    public class LoanApplicationDb
    {
        public void Save(LoanApplication loanApplication)
        {
            Validator.Enforce(loanApplication, "Save");
            // do save logic
        }

        public void Submit(LoanApplication loanApplication)
        {
            Validator.Enforce(loanApplication, "Save", "Submit");
            // do submit logic
        }
    }

Just pass your object to the Valdiator.Enforce() method along with the rules sets you wish to validate against and you are off to the races. Enforce will call Validator.Validate(), check for errors, and throw a ValidationException if it finds any. If it doesn’t find any, it just returns the results of Validate(). If you want to bypass the exception logic, just call Validate() directory.

The above code sample demonstrates how to consume the Validator API, but how do you plug into it? You need to be aware of two components. The first is the IValidator<T> implementation. Here is a sample validator that validates the LoanApplciation against the “Save” rules set.

    public class SaveLoanApplicationValidator : IValidator<LoanApplication>
    {
        public bool AppliesTo(string rulesSet)
        {
            return rulesSet == "Save";
        }

        public IEnumerable<ValidationResult> Validate(LoanApplication value)
        {
            var nameResults = Properties<LoanApplication>
                .For(e => e.Name)
                .Required()
                .Length(2, 100)
                .Message("Name is required.")
                .IgnoreWhiteSpace()
                .Validate(value)
                ;

            var reasonResults = Properties<LoanApplication>
                .For(e => e.Reason)
                .Required()
                .Length(10, 500)
                .IgnoreWhiteSpace()
                .Message("Reason is required.")
                .Validate(value)
                ;


            var accumulatedResults = nameResults
                .Concat(reasonResults)
            ;

            return accumulatedResults;
        }
    }

 

This validator uses the built-in PropertyValidator fluent syntax. Use of the built-in validators is entirely optional. They are included as a convenience in order to provide support for common property-level validations. Simple.Validation handles the simple stuff for you Smile. Where many validation frameworks fall down is when there is some kind of complex validation. In Simple.Validation, complex scenarios are handled the same way as property-level validation. Here’s an example:

        public IEnumerable<ValidationResult> Validate(LoanApplication value)
        {
            if (someComplexCondition)
                yield return new ValidationResult()
                                 {
                                     Context = value,
                                     Message = string.Format(messageFormat, arguments),
                                     PropertyName = "PropertyName",
                                     Severity = ValidationResultSeverity.Error,
                                     Type = MyCustomValidationType.SomeComplexConditionError
                                 };

The ValidationResult is a fairly rich object containing a lot of information about the validation error. The Context is the object being validated. You can (and should) provide a detailed message about the error. PropertyName is not required, but will be useful in many scenarios. Severity has levels of Error, Warning, and Informational. ValidationResult.Type is a property there for arbitrary categorization of validation results.

Okay, so now I’ve written a validator—but how does the static Validator class know about the validator I just wrote?

Validator uses an instance of IValidatorProvider to get the list of validators from the simple. Simple.Validation ships with a DefaultValidatorProvider which you can use as follows:

    public class Configuration
    {
        public void ConfigureValidation()
        {
            var validatorProvider = CreateValidatorProvider();
            RegisterValidators(validatorProvider);
            Validator.SetValidatorProvider(validatorProvider);
        }

        private static void RegisterValidators(DefaultValidatorProvider validatorProvider)
        {
            validatorProvider.RegisterValidator(new SaveLoanApplicationValidator());
            validatorProvider.RegisterValidator(new SubmitLoanApplicationValidator());
        }

        private static DefaultValidatorProvider CreateValidatorProvider()
        {
            var validatorProvider = new DefaultValidatorProvider();
            return validatorProvider;
        }
    }

The implementation of DefaultValidatorProvider is naïve, so you are encouraged to use the IValidatorProvider interface as a wrapper around your favorite Dependency Injection framework. We provide a second nuget package called Simple.Validation.Ninject that contains a NinjectValidatorProvider.

We’ve been using Simple.Valdiation internally for awhile and feel pretty good about its release. However, as it hasn’t been published on the public NuGet feed yet, we’re assigning a prelease version of 0.1. We will conform to semantic versioning conventions as outlined in this post from Phil Haack.

So, run Install-Package Simple.Validation from the Visual Studio Package Manager Console and start using the bits! As always, your feedback is much appreciated.

Happy Coding! Open-mouthed smile

Isg.Specification

I was reading some interesting blogs on the specification pattern today. I was hoping to find a NuGet package, but no such luck. So, I put together the best ideas from the blogs I read and created a new NuGet package called Isg.Specification. Much of this work is not original—my contribution is putting the work of these other developers together in an integrated way and publishing it on NuGet.

Although the write-up of the specification pattern on wikipedia doesn’t mention my specific usage goal, I want to create a parameter object that provides a specification to be used by a LINQ query in EntityFramework. In this way, I can provide a single Get<T>(ParameterObject specification) method to service all Get queries. This simplifies a service interface by removing all the various GetById, GetByName, GetByHasInvoices methods. All that differs between those methods is the predicate applied to the query, so passing the predicate into Get() as a parameter just feels natural. However, I don’t want the caller to be able to specify any predicate they want so using a parameter object that converts itself into a predicate services the purpose of limiting the callers query access as well as simplifying the query API.

Even though my target usage is EntityFramework, and the source code is in the same repository as Isg.EntityFramework, Isg.Specification in no way depends on EntityFramework.

The simplest form of the specification pattern uses simple boolean functions. However, since my target usage is EntityFramework, I needed the functions to be convertible to SQL by the EntityFramework. For this reason, my implementation of ISpecification<T> uses Expression<Func<T, bool>> instead of Func<T, bool> as its signature.

   1:      public interface ISpecification<T>
   2:      {
   3:          Expression<Func<T, bool>> IsSatisfied();
   4:      }

 

The simplest way to get started using the library is to inherit from CompositeSpecification<T>. Using the same sample DbContext I used for Isg.EntityFramework, here is a sample implementation of a Specification object against Customer:

   1:      public class CustomerSpecification : CompositeSpecification<Customer>
   2:      {
   3:          public string Name { get; set; }
   4:          public bool? HasInvoices { get; set; }
   5:   
   6:          protected override IEnumerable<Expression<Func<Customer, bool>>> GetExpressions()
   7:          {
   8:              if (!string.IsNullOrWhiteSpace(Name))
   9:                  yield return ByName();
  10:   
  11:              if (HasInvoices.HasValue)
  12:                  yield return ByHasInvoices();
  13:          }
  14:   
  15:          private Expression<Func<Customer, bool>> ByHasInvoices()
  16:          {
  17:              if (HasInvoices.Value)
  18:                  return c => c.Invoices.Any();
  19:              return c => !c.Invoices.Any();
  20:          }
  21:   
  22:          private Expression<Func<Customer, bool>> ByName()
  23:          {
  24:              return c => c.Name.StartsWith(Name);
  25:          }
  26:      }

 

Usage is pretty easy. ISpecification<T> exposes a single method called IsSatisfied(). Feed the result of this method to a LINQ Where clause and you’re off to the races. CompositeSpecification<T> aggregates the expressions provided by GetExpressions() into a single And-ed expression and uses that for the filter.

In my test cases I create 2 customers, one of whom has invoices and one who does not. You can review the test cases in full here:

Here is sample usage:

   1:          [Test]
   2:          public void HasInvoices()
   3:          {
   4:              // Arrange
   5:              var filter = new CustomerSpecification()
   6:                               {
   7:                                   HasInvoices = true,
   8:                               };
   9:   
  10:              // Act
  11:              using (var context = new CustomerDbContext())
  12:              {
  13:                  var query = context.Customers
  14:                      .Where(filter.IsSatisfied())
  15:                      .ToList();
  16:   
  17:                  // Assert
  18:                  Assert.That(query, Has.Count.EqualTo(1));
  19:                  var result = query.Single();
  20:                  Assert.That(result.Name, Is.EqualTo("Dagny Taggart"));
  21:              }
  22:          }
 
I’ve published Isg.Specification as version 0.1. As always, if you find use for my libraries I would really appreciate your feedback.
 
Enjoy!
Interesting Blogs on the Specification Pattern

I just wanted to give some link-love to the blogs that were helpful to me in implementing the Specification Pattern. Stay tuned for Isg.Specifications on NuGet!

http://davedewinter.com/2009/05/31/linq-expression-trees-and-the-specification-pattern/

http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx

http://iainjmitchell.com/blog/?p=550

http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/

http://devlicio.us/blogs/jeff_perrin/archive/2006/12/13/the-specification-pattern.aspx

Isg.EntityFramework 0.4.2 Released to NuGet

Isg.EntityFramework.Interceptors was renamed to Isg.EntityFramework. The interceptors are still present, but I’ve added some work around EntityFramework Configuration.

Changes:

  • InterceptorDbContext is obsolete. Please use Isg.EntityFramework.DbContextBase
  • DbContextBase adds support for a ModelConfigurationProvider
  • The default ModelConfigurationProvider scans the assembly that your DbContextBase subclass lives in and finds all instances of EntityTypeConfiguration<> and loads them.
  • I added some extension methods to make specifying a non-identity primary key column and computed column a little more straightforward. The EntityFramework method works fine, but isn’t very discoverable. Now it’s Property(<expression>).IsIdentity(false) and Property(<expression>).Computed().
  • Isg.EntityFramework is built against EntityFramework 4.3

Isg.EntityFramework is growing slowly but surely. I would love to hear your ideas about what features you would like to see.

Enjoy!