Build enterprise application with WPF, WCF, Entity Framework and Prism. Tutorial 03.

Update: source code and documentation are now available on CodePlex at this address: http://prismtutorial.codeplex.com/

Value and business validation with Enterprise Library 4.1 and Entity Framework.

In this article I will show you how to validate a domain using the enterprise library 4.1 over the Entity Framework.

First of all I want to talk about the validation and the thousands of implementations you can find over the web. In my opinion there are 2 different types of validation. The value validation and the business validation.

What’s the difference? The first, the value validation should validate an entity against it’s value content. For example, the entity order should have a validation of type NotNull inside it’s Id field, or a LengthValidation inside it’s order number, in order to reflect the corresponding field in the database table. In this way we will execute a value validation in our domain model, before sending the data to the Data Access Layer.

The second validation is the business validation and it can be accomplished with a lot of different ways. The most common is the hard coded way that personally, I don’t really like it. What’s a business validation? Let’s say we have an order entity and we have a rule that says “if the total order is grater than 1,000 $ apply 10% of discount”. This is a business rule that force our entity to change its value after some business considerations.

Available validation framework for NET.

I use for my value validation the Enterprise Library Validation block and I have found it really useful. The only problem is that this framework forces you to use the decorator pattern, so we hard code our entity with the value validation rules. This approach is fine, but only if related to the values. You can also include the value validation in a separate XML file, and this is the solution we will use later.

Another interesting framework is the Validation Framework project on Codeplex, that similar to the EL, uses decorator and generics to validate our entities.

Very powerful but with an high learning curve is the powerful SPRING.NET framework, that inside its application blocks has a space also for the validation. What I really like about SPRING.NET is the fact that you will not hard code anything because the entire validation is in a separate XML file. But remember that the learning curve is pretty complex because SPRING.NET is a full IoC tool, so everything is under the concept of be “Injected”.

Finally, my friend Simone Chiaretta, suggested me this open source framework: Fluent Validation, that has a nice procedural implementation:

  1: using FluentValidation;
  2: 
  3: public class CustomerValidator: AbstractValidator<Customer> {
  4:   public CustomerValidator() {
  5:     RuleFor(customer => customer.Surname).NotEmpty();
  6:     RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
  7:     RuleFor(customer => customer.Company).NotNull();
  8:     RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
  9:     RuleFor(customer => customer.Address).Length(20, 250);
 10:     RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
 11:   }
 12: 
 13:   private bool BeAValidPostcode(string postcode) {
 14:     // custom postcode validating logic goes here
 15:   }
 16: }
 17: 
 18: Customer customer = new Customer();
 19: CustomerValidator validator = new CustomerValidator();
 20: ValidationResult results = validator.Validate(customer);
 21: 
 22: bool validationSucceeded = results.IsValid;
 23: IList<ValidationFailure> failures = results.Errors;
 24: 

The only real business validator framework for NET that I know and that I use in production is IBM iLOG for NET a real powerful engine for business validation that keeps separate your domain model from the business rules. It’s cool and probably it needs just 10 articles only in order to describe it, so you can have a look at the official web site. This is a simple screenshot of how it works:

image

Enterprise Library Validation with Entity Framework.

The first problem we have using this framework is the way we can apply the decorator pattern on it. Why? Because in Visual Studio the EF model is built through a DSL tool called Entity Framework designer. So each time we change the model, our validation decorations are lost through the way …

So let’s add a reference to the enterprise library validation block in our project and let’s try to understand how we can use them in a productive way.

image

The first approach is to overwrite with the partial attribute our domain entity is a way like this one:

  1: public partial class Customer {
  2:     
  3:     public bool IsValid { get { return Validate(); } }
  4: 
  5:     private bool Validate() {
  6:         //validation implementation
  7:         return true;
  8:     }
  9: }

and then validate the entity inside the Validate method. Of course because we cannot use the partial attribute for a property we need to find a different way to grab our validation attributes. From XML?

Good so first of all we need a basic validation class that will validate every single entity using the generics. This solution is the only affordable because the entity generated with EF inherits already from EntityObject class.

  1: public static class EntityValidator<T> {
  2: 
  3:     public static Dictionary<string,string> ValidationErrors { get; set; }
  4: 
  5:     public static bool Validate<T>(T entity) {
  6:         ValidationResults results = Validation.ValidateFromConfiguration<T>(entity);
  7:         if (results.IsValid) {
  8:             return true;
  9:         } else {
 10:             foreach (var error in results) {
 11:                 ValidationErrors.Add(error.Key, error.Message);
 12:             }
 13:             return false;
 14:         }
 15:     }
 16: 
 17: }
 18: 

Now we can do the validation in this way from the repository, for example:

  1: public int Add<T>(T entity) {
  2:     ADVConnection context = GetObjectContext();
  3:     if (EntityValidator<T>.Validate(entity)) {
  4:         context.AddObject(typeof(T).Name, entity);
  5:         int result = context.SaveChanges();
  6:         ReleaseObjectContextIfNotReused();
  7:         return result;
  8:     }
  9:     return -1;
 10: }
 11: 

An then we can handle that return –1 in a way that we prefer, maybe we can catch it in the “presenter” and interact with the UI. We just need to keep alive the validation errors generated by the method Validate<T>.

Entity Framework mapping file.

The Entity Framework works similar to NHibernate, so for each business object we have a mapping file. If you open the .edmx file with a right click->open with-> XML editor, you will get an XML representation of your model, similar to this file:

  1: <EntityType Name="Customer">
  2:   <Key>
  3:     <PropertyRef Name="CustomerID" />
  4:   </Key>
  5:   <Property Name="CustomerID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
  6:   <Property Name="NameStyle" Type="bit" Nullable="false" />
  7:   <Property Name="Title" Type="nvarchar" MaxLength="8" />
  8:   <Property Name="FirstName" Type="nvarchar" Nullable="false" MaxLength="50" />
  9:   <Property Name="MiddleName" Type="nvarchar" MaxLength="50" />
 10:   <Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="50" />
 11: 

As you can see, we have already all the rules in place, so we do not need to declare anything. For example, the EF already knows that the Title field should be at most, 8 characters long and can be null. Unfortunately, with the version 3 of EF those rules cannot be connected to the Enterprise Library, easily.

How we can handle this in our static validator using generics?

Close you Visual Studio solution, and navigate to your Enterprise Library installation folder.

Open the .exe called EntLibConfig.exe. The first screenshot you will se is something like this:

image

Click on the file menu and open the app.config file in the layer PrismTutorial.DataLayer.App.Config  and you will load the configuration file inside this tool.

Now, click on the root of your application and select new validation application block. The result should something like this:

image

Now we can create a Rule, or a Rule Set and then we can load our domain model and associate those rules with every entity.

In order to load the domain model, choose new Type, in the type window, select the PrismTutorial.DataLayer.DomainModel.dll using this button:

image

At this point you can use the search filter of this window to load one entity per time. I started with the Customer entity. The final result is this one:

image

Finally, right click on the customer and select new rule set and give it a name. In this rule set we will contain all the rules associated with this entity.

Now, on the ruleset node, choose select members and here it’s the magic!!

image

Finally, you will have now the node Customer showing for every loaded field, an additional node. From here you can select any field and add a new validator. You can include the message template, the type of validation and so on …

This is my final result:

image

If you open Visual Studio, you will find the app.config file changed. Of course you cannot change the app.config file when the solution is open because in my case, I work under source control and the app.config is locked.

  1:   <configSections>
  2:     <section name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Configuration.ValidationSettings, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  3:     <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  4:   </configSections>
  5: 

And the Customer validation rules.

  1:     <type defaultRuleset="CustomerValidation" assemblyName="PrismTutorial.DataLayer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d5210384f83ebb19"
  2:       name="PrismTutorial.DataLayer.Customer">
  3:       <ruleset name="CustomerValidation">
  4:         <properties>
  5:           <property name="CustomerID" />
  6:           <property name="NameStyle" />
  7:           <property name="Title" />
  8:           <property name="FirstName" />
  9:           <property name="MiddleName" />
 10:           <property name="LastName" />
 11:           <property name="Suffix" />
 12:           <property name="CompanyName">
 13:             <validator negated="false" messageTemplate="Company name cannot be null."
 14:               messageTemplateResourceName="" messageTemplateResourceType=""
 15:               tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.NotNullValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
 16:               name="Not Null Validator" />
 17:             <validator lowerBound="0" lowerBoundType="Ignore" upperBound="100"
 18:               upperBoundType="Inclusive" negated="false" messageTemplate="Company Name cannot be long more than 100 characters."
 19:               messageTemplateResourceName="" messageTemplateResourceType=""
 20:               tag="" type="Microsoft.Practices.EnterpriseLibrary.Validation.Validators.StringLengthValidator, Microsoft.Practices.EnterpriseLibrary.Validation, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
 21:               name="String Length Validator" />

Finally I just want to remember you that you can integrate this editor inside Visual Studio 2008 SP1.

Note: With Visual Studio 2010 and the Entity Framework 4.0, this problem is going to be deprecated because the EF 4 allows us to build POCO object like in NHibernate, so we can then use the decorator pattern or any other type of validation pattern.

Tags: