Our Telerik Kendo UI Case Study 2014 Released – Enterprise Benefits and Value Added

Telerik Kendo UI Case Study is out, quick read on CBRE enterprise benefits leveraging Kendo UI Professional.

2014-11-03_14-07-52

Customer Profile
CB Richard Ellis (CBRE) is one of the world’s premier full-service real estate companies, with 349 offices in 42 countries and over 44,000 employees. The company’s $223 billion in transactions span sales and leasing, loan originations, property and corporate facilities management and much more, making CBRE the global leader in real estate services and investment.

Business Situation
CBRE has over 100 mobile apps–some public facing–but most are unique to the company internal operations. However, disparate development platforms scattered around the world made it difficult to maximize economies of scale. The company needed a framework to deliver application portability to a spectrum of devices and operating systems, while at the same time, providing the “wow” factor field agents needed to close real estate deals.

Solution
When CBRE application development shifted increasingly to HTML5 and CSS3, the development team conducted a thorough review of the competitive landscape and after an exhaustive research they chose the Telerik Kendo UI® framework.

Benefits

  • Less resources needed to develop, test and keep things consistent for a wide array of machines, browsers and versions
  • Development time savings of 35%-50%
  • Confidence that each app will run flawlessly on whatever device selected: iPad, iPhone, Android tablet, Windows Phone, Mac or Windows desktop

http://www.telerik.com/company/success-stories/details/real-estate-giant-cbre-cuts-mobile-app-dev-time-by-50-with-telerik

http://www.telerik.com/docs/default-source/case-studies-documents/cbre_casestudy_2.pdf

CBRE Telerik Kendo UI Enterprise Case Study 2014 (PDF Download)

Building an Extensible Fluent Validation Framework using Generic Funcs and Wiring it up to MVC 4 with ModelValidatorProvider and ModelValidator

Live demo http://longle.azurewebsites.net/customer, courtesy of Windows Azure free 10 Websites, will keep this out there for as long as it’s free 🙂

We will start off in a pre-baked solution from my last post http://blog.longle.net/2013/05/17/generically-implementing-the-unit-of-work-repository-pattern-with-entity-framework-in-mvc-simplifying-entity-graphs-part-2-mvc-4-di-ioc-with-mef-attributeless-conventions/ using Unity 3.0 as our DI framework of choice.

Before we starts let’s define some of key architecture & design principles we are attempting to achieve here.

  • Validation Framework can run in any .NET technology space e.g. WPF, MVC, ASP.NET WebForms, ASP.NET MVC, SilverLight, WF, Windows Services, WCF, etc..
  • Validation Framework is extensible, and easy to do so.
  • Validation Framework will support reusable validations so that we can reuse them across the enterprise.
  • Validation Framework will support ad-hoc validations, meaning validations, that potentially will only be used once, that are not common validations, and very specific to a given entity with a unique use case.
  • Validation Framework can easily be plugged in e.g such as the MVC 4 run-time, not requiring developer’s to do anything different than they are today to validate their models.

We have a lot to cover so let’s dive right into the Validation project and its’ code!

Validation.Validator.cs


namespace Validation
{
    public class Validator<TModel> : IValidator
    {
        private readonly List<ValidationResult> _validationResults;
        private readonly List<Validation<TModel>> _validations;

        public Validator()
        {
            _validations = new List<Validation<TModel>>();
            _validationResults = new List<ValidationResult>();
        }

        public List<ValidationResult> Validate(object model)
        {
            foreach (var validation in _validations)
            {
                validation.OnValidating();
                var validater = validation.GetValidater();

                if (!validater((TModel) model))
                    _validationResults.Add(validation.GetValidationResult());
            }

            return _validationResults;
        }

        public Validation<TModel> AddValidation(Validation<TModel> validationRule)
        {
            _validations.Add(validationRule);
            return validationRule;
        }
    }
}

This is probably one of the most important class of our Validation Framework, it primary responsibility are:

  • Iterating through all of our validations for a given entity
  • Storing the result for each of the validations

Validation.Validation.cs


    public class Validation<TModel>
    {
        private string _errorMessage;
        private string _propertyName;
        private Func<TModel, bool> _validater;
        private Expression<Func<TModel, object>> _property;

        public Expression<Func<TModel, object>> GetProperty()
        {
            return _property;
        }

        public Validation<TModel> SetProperty(Expression<Func<TModel, object>> property)
        {
            _property = property;
            return this;
        }

        public string GetPropertyName()
        {
            var memberExpression = GetProperty().Body as MemberExpression ?? ((UnaryExpression) GetProperty().Body).Operand as MemberExpression;

            if (memberExpression == null)
            {
                _propertyName = default(string);
                return _propertyName;
            }

            _propertyName = memberExpression.Member.Name;

            return _propertyName;
        }

        public Validation<TModel> SetErrorMessage(string errorMessage)
        {
            _errorMessage = errorMessage;
            return this;
        }

        public Validation<TModel> SetValidater(Func<TModel, bool> validater)
        {
            _validater = validater;
            return this;
        }

        public Func<TModel, bool> GetValidater()
        {
            return _validater;
        }

        public string GetErrorMessage()
        {
            return _errorMessage;
        }

        public ValidationResult GetValidationResult()
        {
            return new ValidationResult {ErrorMessage = GetErrorMessage(), PropertyName = GetPropertyName()};
        }

        public virtual void OnValidating()
        {
            if (string.IsNullOrEmpty(_errorMessage))
                _errorMessage = GetPropertyName() + " is not valid";
        }}

The Validation class is primarily responsible for:

  • Keeping track which property of the entity it’s its validation is for.
  • Setting the appropriate validation result and message.

Now really this is really all you need to start validating your entities/models. Although, there are some other classes that are in the Validation project, they are really not needed to start validating. They are there to help us later wire up our Validation Framework to MVC 4. With that being said let’s wire up our first validation, all you need to do is implement the the Validator class.

I’ve added a UnitTest project with two test class, one is simply a dummy model with fictitious property names, the property names are named after the type of validation we are performing on the property so that we can easily understand what type of validation is happening on each of them. The second class MyValidator is where are validations actually reside for validating MyModel.cs.

Notice all the validations are stored in the MyValidator.cs class and that our MyModel.cs knows nothing about any validation business. More importantly our validation is completely decoupled from our entities, giving us nice separation of concerns.

Validation.Tests.MyModel.cs

Note: Again, The property names here are named so that we can easily see what types of validations are happening for each of them. Obviously in the real world they would be named FirstName, LastName, Age, versus Compare1, Compare2, Regex, etc. :p


namespace Validation.Test
{
    public class MyModel
    {
        public string Compare1 { get; set; }
        public string Compare2 { get; set; }
        public string CreditCard { get; set; }
        public string Id { get; set; }
        public string Length { get; set; }
        public string Range { get; set; }
        public string Regex { get; set; }
        public string Required { get; set; }
        public string IpAddress { get; set; }
        public string Email { get; set; }
    }
}

Validation.Tests.MyValidator.cs
A simple test/sample validator implementation so that we can code up a quick unit test.


namespace Validation.Test
{
    public class MyValidator : Validator<MyModel>
    {
        public MyValidator()
        {
            this.ValidateCompare(m => m.Compare1, m => m.Compare2)
                .WithDataType(ValidationDataType.Integer)
                .WithOperator(ValidationOperator.GreaterThan);

            this.ValidateCreditCard(m => m.CreditCard);

            this.ValidateId(m => m.Id);

            this.ValidateLength(m => m.Length)
                .WithMax(5)
                .WithMin(1);

            this.ValidateRange(m => m.Range)
                .WithDataType(ValidationDataType.Integer)
                .WithMin(1)
                .WithMax(5);

            this.ValidateRegex(m => m.Regex)
                .SetPattern(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*")
                .SetErrorMessage("Email must be in valid format");

            this.ValidateRequired(m => m.Required);

            this.ValidateIpAddress(m => m.IpAddress);

            this.ValidateEmail(m => m.Email);

            this.AddValidation()
                .SetProperty(m => m.Email)
                .SetValidater(model => !string.IsNullOrEmpty(model.Email))
                .SetErrorMessage("Email is required");
        }
    }
}

Here we have some simple validation implemented and wired up for our MyModel.cs entity. Here we are using some of the out of the box validations I’ve coded up, and some ad-hoc validations we are able to add to our Validator that the Validation Framework provides e.g. validating and Id, length, range, using Regex, required, IP address, email, etc.. Obviously you can easily add your own reusable validation, and again add ad-hoc (lines 34-37) validations that will probably only be specific to a given entity.

Now let’s test our validation by coding up a quick unit test.

ValidationTests.UnitTest1.cs


namespace Validation.Test
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var myModel = new MyModel();
            var myValidator = new MyValidator();
            var validationResults = myValidator.Validate(myModel);
            
            Assert.AreEqual(validationResults.Count, 4);
            Assert.AreEqual(validationResults[0].PropertyName, "Compare1" );
            Assert.AreEqual(validationResults[1].PropertyName, "Id");
            Assert.AreEqual(validationResults[2].PropertyName, "Required");
            Assert.AreEqual(validationResults[3].PropertyName, "Email");
        }
    }
}

If we run our unit test, we can see that MyModel.cs was nicely validated…!

6-3-2013 2-41-04 PM

Now, this is great, but how do we seamlessly wire this up to MVC 4..?! Good question, let’s get started. To wire up our new Validation Framework with the MVC 4 run-time there are a couple of things we need to do.

First is to implement the ModelValidatorProvider (http://msdn.microsoft.com/en-us/library/system.web.mvc.modelvalidatorprovider(v=vs.98).aspx), this will provide the MVC 4 runtime the necessary implementation to get a set of validations for a model.

Validation.CustomModelValidatorProvider.cs


namespace Validation
{
    public class CustomModelValidatorProvider : ModelValidatorProvider
    {
        public override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context)
        {
            var isPropertyValidation = metadata.ContainerType != null && !String.IsNullOrEmpty(metadata.PropertyName);

            if (isPropertyValidation) yield break;

            var validatorFactory = new ValidatorFactory();
            var validator = validatorFactory.GetValidator(metadata.ModelType, metadata.Model);

            if (validator != null)
                yield return new CustomModelValidator(metadata, context, validator);
        }
    }
}

When implementing the ModeValidatorProvider we see that we do need a factory of some sort to new up an instance of the right Validator to validate our model. We accomplish this with the ValidatorFactory. This class is responsible for discovering the ValidatorAttribute that the MVC model should be decorated with has the Validator type to be activated to validate the model.

Validation.ValidatorFactory.cs


namespace Validation
{
    public class ValidatorFactory
    {
        public IValidator GetValidator(Type type, object model)
        {
            var validatorAttributes = type.GetCustomAttributes(typeof (ValidatorAttribute), true);

            if (validatorAttributes.Length > 0)
            {
                var validatorAttribute = (ValidatorAttribute) validatorAttributes[0];
                return Activator.CreateInstance(validatorAttribute.Validator) as IValidator;
            }   
            return null;
        }
    }
}

The ValidatorAttribute is pretty straight forward, it’s an attribute that accepts a type, which is the Validator type we need to activate to validate the model.

Validation.ValidatorAttribute.cs


namespace Validation
{
    [AttributeUsage(AttributeTargets.Class)]
    public class ValidatorAttribute : Attribute
    {
        private readonly Type _validator;

        public ValidatorAttribute(Type validator)
        {
            _validator = validator;
        }


        public Type Validator
        {
            get { return _validator; }
        }
    }
}

Let’s take a look at our Customer model that is decorated with the ValidatorAttribute so that our ValidatorFactory knows which Validator to activate for it, in our case CustomerValidator.cs.

Data.Models.Customer.cs


namespace Data.Models
{
    [Validator(typeof (CustomerValidator))]
    public class Customer : IObjectState
    {
        public Customer()
        {
            Orders = new List<Order>();
            CustomerDemographics = new List<CustomerDemographic>();
        }

        public string CustomerID { get; set; }
        public string CompanyName { get; set; }
        public string ContactName { get; set; }
        public string ContactTitle { get; set; }
        public string Address { get; set; }
        public string City { get; set; }
        public string Region { get; set; }
        public string PostalCode { get; set; }
        public string Country { get; set; }
        public string Phone { get; set; }
        public string Fax { get; set; }
        public virtual ICollection<Order> Orders { get; set; }
        public virtual ICollection<CustomerDemographic> CustomerDemographics { get; set; }
        public ObjectState State { get; set; }
    }
}

Second, we need to implement the ModelValidator (http://msdn.microsoft.com/en-us/library/system.web.mvc.modelvalidator(v=vs.108).aspx), this will provide the MVC 4 runtime to call into our Validation Framework and execute our Validator.Validate(object model) method and return a set of ValidationResults. Once our ValidationResult payload is returned we will then need to map it back to MVC’s ModelValidationResult so that it can display our validation messages correctly.

Validation.CustomModelValidator.cs


namespace Validation
{
    public class CustomModelValidator : ModelValidator
    {
        private readonly IValidator _validator;

        public CustomModelValidator(ModelMetadata metadata, ControllerContext controllerContext, IValidator validator)
            : base(metadata, controllerContext)
        {
            _validator = validator;
        }

        public override IEnumerable<ModelValidationResult> Validate(object container)
        {
            var validationResults = _validator.Validate(Metadata.Model);

            return validationResults
                .Select(validationResult => 
                    new ModelValidationResult
                        {
                            MemberName = validationResult.PropertyName, 
                            Message = validationResult.ErrorMessage
                        });
        }
    }
}

Finally we need to register our Validation.CustomModelValidatorProvider.cs implementation with the MVC runtime.

Web.Global.asax.cs


namespace Web
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            Bootstrapper.Initialise();

            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);
            AuthConfig.RegisterAuth();

            // Add our custom ModelValiidatorProvider for MVC runtime
            ModelValidatorProviders.Providers.Add(new CustomModelValidatorProvider());
        }
    }
}

Now let’s start off by validating one of our existing entities Entites.Customer.cs. You can really place your validation objects anywhere you’d like, for simplicity sake I’ll go ahead and place them in the same project as our Entities under a folder named Validations.

Entities.Validators.CustomerValidator.cs


namespace Entities.Validations
{
    internal class CustomerValidator : Validator<Customer>
    {
        public CustomerValidator()
        {
            this.ValidateId(m => m.CustomerID);

            this.ValidateLength(m => m.CompanyName)
                .WithMax(5)
                .WithMin(1);

            this.ValidateRequired(m => m.ContactName);

            this.AddValidation()
                .SetProperty(m => m.City)
                .SetValidater(model => !string.IsNullOrEmpty(model.City))
                .SetErrorMessage("Customer city is required");
        }
    }
}

Now let’s edit our existing CustomController and add two more actions for editing our Customer entity.

Web.Controllers.CustomerController.cs


namespace Web.Controllers
{
    public class CustomerController : Controller
    {
        private readonly IUnitOfWork _unitOfWork;

        public CustomerController(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            int totalCustomerCount;

            var customers =
                _unitOfWork.Repository<Customer>()
                    .Query()
                    .Include(i => i.Orders)
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            return View();
        }

        [HttpGet]
        public ActionResult Edit(string id)
        {
            var customer = _unitOfWork.Repository<Customer>().FindById(id);
            return View(customer);
        }

        [HttpPost]
        public ActionResult Edit(Customer customer)
        {
            if (ModelState.IsValid)
                RedirectToAction("Edit");
            
            _unitOfWork.Repository<Customer>().Update(customer);
            _unitOfWork.Save();

            return View(customer);
        }
    }
}

Notice how we are calling the MVC ModelState.IsValid, and when we debugging this, we see that the MVC run-time will invoke our custom Validation Framework.

6-3-2013 3-30-50 PM

Our error message from Entities.Validation.CustomerValidator.cs.

6-3-2013 3-31-57 PM

All of the out of the box Validators that are included in the example download, follow the described pattern listed below, this is also how you would extend or add your own reusable validations to the framework.

  1. Extend the Validator, by writing an Extension method
  2. Instantiating a fluent helper class for the validation
  3. Setting the property to be validated
  4. Setting the validation logic
  5. Adding the the validation to stack of validations to the Validator instance

Let’s take a quick look at one of the out of the box validations e.g. ValidateLength.

Validation.Validators.ValidateLengthExtension.cs


namespace Validation.Validators
{
    public static class ValidateLengthExtension
    {
        public static ValidateLengthFluentHelper<TModel> ValidateLength<TModel>(this Validator<TModel> validator, Expression<Func<TModel, object>> property)
        {
            var fluentHelper = new ValidateLengthFluentHelper<TModel>();

            fluentHelper.SetProperty(property);
            fluentHelper.SetValidater(model =>
                {
                    var value = property.GetPropertyValue(model) as string;

                    return string.IsNullOrEmpty(value) || value.Length >= fluentHelper.GetMin() && value.Length <= fluentHelper.GetMax();
                });

            validator.AddValidation(fluentHelper);

            return fluentHelper;
        }
    }
}

To provide a nice and easy to use fluent API experience, let’s take a look at the fluent helper class for this validation.

Validation.Validators.ValidateLengthFluentHelper.cs


namespace Validation.Validators
{
    public class ValidateLengthFluentHelper<TModel> : Validation<TModel>
    {
        private int _max;
        private int _min;

        public override void OnValidating()
        {
            if (String.IsNullOrEmpty(GetErrorMessage()))
                SetErrorMessage(GetPropertyName() + " must be between " + _min + " and " + _max + " characters long.");
        }

        public int GetMin()
        {
            return _min;
        }

        public int GetMax()
        {
            return _max;
        }

        public new ValidateLengthFluentHelper<TModel> SetProperty(Expression<Func<TModel, object>> propertySelector)
        {
            base.SetProperty(propertySelector);
            return this;
        }

        public ValidateLengthFluentHelper<TModel> WithMin(int min)
        {
            _min = min;
            return this;
        }

        public ValidateLengthFluentHelper<TModel> WithMax(int max)
        {
            _max = max;
            return this;
        }
    }
}

To use this is fairly straight forward and simple..!

ValidationTest.MyValidator.cs


            this.ValidateLength(m => m.Length)
                .WithMax(5)
                .WithMin(1);


Support for Ad-Hoc Validations with Generic Funcs using AddValidation() Fluent Method

Finally, let’s quickly go over adding ad-hoc validations by adding in-line Lambda’s or Generic Funcs, all you hvae to do is call AddValidation() and using the fluent API, and make sure your generic func accepts a TModel (could be of any object type) and returns a Boolean. In the sample code below we are doing a simple ad-hoc validation for the property Email, validating if there’s a value or not and returning an validation message.

ValidationTest.MyValidator.cs


            this.AddValidation()
                .SetProperty(m => m.Email)
                .SetValidater(model => !string.IsNullOrEmpty(model.Email))
                .SetErrorMessage("Email is required");


There you have it, a Validation Framework registered and wired up to the MVC 4 run-time.

Happy Coding..! 🙂

Download sample application.

https://skydrive.live.com/redir?resid=949A1C97C2A17906!5153&authkey=!AKbcAGKuETlcm6M

Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs

Update: 02/24/2014 – v3.2 released, improved API and reusable queries with the variation of the Query Object Pattern. Breaking change: Framework now ships returning all things TEntity or IEnumberable for compartmentalization, you will need to change the Repository.cs (see below, what methods signatures to change) if IQueryable is preferred over IEnumerable, IEnumerable is preferred as a best practice (http://genericunitofworkandrepositories.codeplex.com/documentation).

Update [01/06/2014] Quick start online video: http://blog.longle.net/2014/01/06/unit-of-work-unity-3-quick-start-video/

1-3-2014 5-43-38 PM

Update [11/18/2013]: Added mocked DbContext and DbSet and example Unit Tests using the mocks, download: https://genericunitofworkandrepositories.codeplex.com

This will be part two of a six part series of blog posts.

  1. Modern Web Application Layered High Level Architecture with SPA, MVC, Web API, EF, Kendo UI, OData
  2. Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs
  3. MVC 4, Kendo UI, SPA with Layout, View, Router & MVVM
  4. MVC 4, Web API, OData, EF, Kendo UI, Grid, Datasource (CRUD) with MVVM
  5. MVC 4, Web API, OData, EF, Kendo UI, Binding a Form to Datasource (CRUD) with MVVM
  6. Upgrading to Async with Entity Framework, MVC, OData AsyncEntitySetController, Kendo UI, Glimpse & Generic Unit of Work Repository Framework v2.0

Update: 09/18/2013 – Sample application and source code has been uploaded to CodePlex: https://genericunitofworkandrepositories.codeplex.com, updated project to VS2013, Twitter Bootstrap, MVC 5, EF6, Kendo UI Bootstrap theme, project redeployed to Windows Azure Website.

Update: 07/30/2013 – To see this implementation with DI & IoC with EntLib Unity v3.0, see post: Bounded DbContext with Generic Unit of Work, Generic Repositories, Entity Framework 6 & EntLib Unity 3.0 in MVC 4.

Update: 06/21/2013 – Bug fix: Issue with deleting objects by Id in Repository.Delete(object Id). Updated blog post, and sample solution and added live demo link.

Live demo: http://longle.azurewebsites.net

First off let’s elegantly setup our solution, and prep it for real world development. We have our solution broken up into four different projects, now let’s talk about the “why?”.

5-8-2013 9-08-17 PM

Data Project (Data Access Layer)

This is where all of our ORM tooling related objects reside. In our case the EF (Entity Framework 6.0 Alpha 3) DataContext, Mappings, Migrations, etc. This give is nice separation, control and isolation of where any persistence related objects live. If ever, one day we need to change the tool of choice, or even upgrade, there’s only one layer or project to do this in, the Data project.

5-8-2013 10-08-26 PM

Entities Project (Domain Layer)
The Entities project is where all of our POCO (Plan Old C# Objects) objects will live. POCO’s should be very ignorant objects that pretty much have nothing in them but the structure of your data. With that being said, typically anything outside our Repository layer e.g. presentation layer (MVC), services layer (will cover in next post) should be completely ignorant to any persistence tool or technology e.g. NHibernate, eXpressPersistent, OpenAccess, EF (our case), etc.

5-8-2013 10-09-31 PM

Repository (Layer)
This is where our UoW (Unit of Work) pattern will be implemented as well as our Repository implementation. Our UoW implementation will handle most of our usual CRUD activities.

Two important objectives we will try to with our UoW pattern implementation are:

  1. Abstract away the ORM tool, in our case EF.
  2. Ensuring that all interactions with the database are happening under one DbContext instance per page request.

Obviously there are many other benefits, such giving us the ability to implement different variations of our UoW, potentially wire up to different types of repositories. For purposes of this article, we’ll stake focus on our two primary objectives, and I’ll cover the other benefits in later posts.

Web Project (Presentation Layer)
This is our presentation layer, for the purposes of the blog, we will use MVC (ASP.NET MVC 4). Again, this project should not have any dependent code on EF assembly, therefore that should not be any references to the EF assembly, it should only reference our Repository project for data access.

Refactoring the NorthwindContext for an Abstracted and Cleaner Implementation

Now that we’ve gone over the solution and it’s projects, let’s do a little bit of refactoring and cleaning up with our EF code.

Data.NorthwindDataContext.cs

Before:


    public class NorthwindContext : DbContext
    {
        static NorthwindContext()
        {
            Database.SetInitializer<NorthwindContext>(null);
        }

        public NorthwindContext()
            : base("Name=NorthwindContext")
        {
        }

        public DbSet Category Categories { get; set; }
        public DbSet CustomerDemographic CustomerDemographics { get; set; }
        public DbSet Customer Customers { get; set; }
        public DbSet Employee Employees { get; set; }
        public DbSet OrderDetail Order_Details { get; set; }
        public DbSet Order Orders { get; set; }
        public DbSet Product Products { get; set; }
        public DbSet Region Regions { get; set; }
        public DbSet Shipper Shippers { get; set; }
        public DbSet Supplier Suppliers { get; set; }
        public DbSet Territory Territories { get; set; }
        public DbSet Invoice Invoices { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new CustomerDemographicMap());
            modelBuilder.Configurations.Add(new CustomerMap());
            modelBuilder.Configurations.Add(new EmployeeMap());
            modelBuilder.Configurations.Add(new Order_DetailMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new RegionMap());
            modelBuilder.Configurations.Add(new ShipperMap());
            modelBuilder.Configurations.Add(new SupplierMap());
            modelBuilder.Configurations.Add(new TerritoryMap());
            modelBuilder.Configurations.Add(new InvoiceMap());
        }
    }

After:

     public class NorthwindContext : DbContext, IDbContext
    {
        static NorthwindContext()
        {
            Database.SetInitializer<NorthwindContext>(null);
        }

        public NorthwindContext()
            : base("Name=NorthwindContext")
        {
        }

        public new IDbSet<T> Set<T>() where T : class
        {
            return base.Set<T>();
        }

        public override int SaveChanges()
        {
            this.ApplyStateChanges();
            return base.SaveChanges();
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new CustomerDemographicMap());
            modelBuilder.Configurations.Add(new CustomerMap());
            modelBuilder.Configurations.Add(new EmployeeMap());
            modelBuilder.Configurations.Add(new Order_DetailMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new RegionMap());
            modelBuilder.Configurations.Add(new ShipperMap());
            modelBuilder.Configurations.Add(new SupplierMap());
            modelBuilder.Configurations.Add(new TerritoryMap());
            modelBuilder.Configurations.Add(new InvoiceMap());
        }
    }

We can see that our DbContext is now much cleaner, and that it implements IDbContext. IDbContext will be the abstraction we will be working with when interacting with it’s concrete implementation, NorthwindContext.

Best Practice, Coding Against Abstractions or Interfaces

Abstractions serve as a nice flexibility point later, allowing us to implement different variations of the abstraction (interface). This will be very useful later when we implement DI (Dependency Injection and IoC (Inverse of Control) patterns. Coding to an abstraction will also help us easily create unit test, allowing us to inject faked or mocked instances as well. If your a bit unclear on how this helps set stage for DI, IoC and Unit Testing, no worries, I’ll cover these topics in the next post.

Data.IDbContext.cs


namespace Data
{
    public interface IDbContext
    {
        IDbSet<T> Set<T>() where T : class;
        int SaveChanges();
        DbEntityEntry Entry(object o);
        void Dispose();
    }
}

Now, let’s take take a look at what’s all in our Repository project, where our generic extensible repositories will reside.

5-10-2013 7-02-10 PM

IUnitOfWork This is simply the contract or abstraction that we will be working with, when interacting with it’s concrete implementation which will be UnitOfWork object.

Repository.IUnitOfwork.cs



namespace Repository
{
    public interface IUnitOfWork
    {
        void Dispose();
        void Save();
        void Dispose(bool disposing);
        IRepository<T> Repository<T>() where T : class;
    }
}

Concrete Implementation of IUnitOfWork.cs


namespace Repository
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDbContext _context;

        private bool _disposed;
        private Hashtable _repositories;

        public UnitOfWork(IDbContext context)
        {
            _context = context;
        }

        public UnitOfWork()
        {
            _context = new NorthwindContext();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        public void Save()
        {
            _context.SaveChanges();
        }

        public virtual void Dispose(bool disposing)
        {
            if (!_disposed)
                if (disposing)
                    _context.Dispose();

            _disposed = true;
        }

        public IRepository<T> Repository<T>() where T : class
        {
            if (_repositories == null)
                _repositories = new Hashtable();

            var type = typeof (T).Name;

            if (!_repositories.ContainsKey(type))
            {
                var repositoryType = typeof (Repository<>);

                var repositoryInstance = 
                    Activator.CreateInstance(repositoryType
                            .MakeGenericType(typeof (T)), _context);
                
                _repositories.Add(type, repositoryInstance);
            }

            return (IRepository<T>) _repositories[type];
        }
    }
}

Let’s take a look at our IRepository Repository() method here in our UnitOfWork implementation. Here we are storing all the activated instances of repositories for each and every requests. One there is a request for a given repository we will first check to see if our Hashtable (container to hold all of our activated repository instances) has been created, if not, will go ahead and create our container. Next, we’ll scan our container to see if the requested repository instance has already been created, if it has, then will return it, if it hasn’t, we will activate the requested repository instance, store it in our container, and then return it. If it helps, you can think of this as lazy loading our repository instances, meaning we are only creating repository instances on demand, this allows us to only create the repository instances needed for a given web request. Last but not least, notice here how we are following best practices mentioned earlier, we are not return the concrete implementation for the Repository, but the abstraction, IRepository.

Repository.IRepository.cs


namespace Repository
{
    public interface IRepository<TEntity> where TEntity : class
    {
        TEntity FindById(object id);
        void InsertGraph(TEntity entity);
        void Update(TEntity entity);
        void Delete(object id);
        void Delete(TEntity entity);
        void Insert(TEntity entity);
        RepositoryQuery<TEntity> Query();
    }
}


Repository.Repository.cs


    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        internal IDbContext Context;
        internal IDbSet<TEntity> DbSet;

        public Repository(IDbContext context)
        {
            Context = context;
            DbSet = context.Set<TEntity>();
        }

        public virtual TEntity FindById(object id)
        {
            return DbSet.Find(id);
        }

        public virtual void InsertGraph(TEntity entity)
        {
            DbSet.Add(entity);
        }

        public virtual void Update(TEntity entity)
        {
            DbSet.Attach(entity);
        }

        public virtual void Delete(object id)
        {
            var entity = DbSet.Find(id);
            var objectState = entity as IObjectState;
            if (objectState != null) 
                objectState.State = ObjectState.Deleted;
            Delete(entity);
        }

        public virtual void Delete(TEntity entity)
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
        }

        public virtual void Insert(TEntity entity)
        {
            DbSet.Attach(entity);
        }

        public virtual RepositoryQuery<TEntity> Query()
        {
            var repositoryGetFluentHelper =
                new RepositoryQuery<TEntity>(this);

            return repositoryGetFluentHelper;
        }

        internal IQueryable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>,
                IOrderedQueryable<TEntity>> orderBy = null,
            List<Expression<Func<TEntity, object>>>
                includeProperties = null,
            int? page = null,
            int? pageSize = null)
        {
            IQueryable<TEntity> query = DbSet;
            
            if (includeProperties != null)
                includeProperties.ForEach(i => { query = query.Include(i); });

            if (filter != null)
                query = query.Where(filter);

            if (orderBy != null)
                query = orderBy(query);

            if (page != null && pageSize != null)
                query = query
                    .Skip((page.Value - 1)*pageSize.Value)
                    .Take(pageSize.Value);

            return query;
        }
    }

Our generic implementation for Repository allows us to have have all our basic heavy lifting of a Repository out of the box for any one of our Entities. All we have to do is request for the Repository of interest by passing in the Entity e.g.

UnitOfWork.Repository<Customer>

will give us the Customer Repository with all our out of the box plumbing available.

Let’s take a quick look at our Get method in the Repository implementation.


        internal IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>,
                IOrderedQueryable<TEntity>> orderBy = null,
            List<Expression<Func<TEntity, object>>>
                includeProperties = null,
            int? page = null,
            int? pageSize = null)
        {
            IQueryable<TEntity> query = DbSet;
            
            if (includeProperties != null)
                includeProperties.ForEach(i => query.Include(i));

            if (filter != null)
                query = query.Where(filter);

            if (orderBy != null)
                query = orderBy(query);

            if (page != null && pageSize != null)
                query = query
                    .Skip((page.Value - 1)*pageSize.Value)
                    .Take(pageSize.Value);


            return query.ToList();
        }

The Get method here, handles fetching data. It handles querying the data supporting a filtering, ordering, paging, and eager loading of child types, so that we can make one round trip and eager load the entity graph.

We notice here that the method is marked “internal”, this is because we only want the Get method here to be accessible to objects with the same assembly, Repository.dll. We will expose the Get method via the Query method and return the RepositoryQuery object to provide a fluent “ish” api, so that’s its a bit more easy and intuitive for our developers when querying with our Repository layer. Note, only methods in our RepositoryQuery will actually invoke the internal Get method, again, which is why we went ahead and marked the Get method internal.

Repository.RepositoryQuery.cs (our fluent api helper class)


    public sealed class RepositoryQuery<TEntity> where TEntity : class
    {
        private readonly List<Expression<Func<TEntity, object>>> 
            _includeProperties;

        private readonly Repository<TEntity> _repository;
        private Expression<Func<TEntity, bool>> _filter;
        private Func<IQueryable<TEntity>, 
            IOrderedQueryable<TEntity>> _orderByQuerable;
        private int? _page;
        private int? _pageSize;

        public RepositoryQuery(Repository<TEntity> repository)
        {
            _repository = repository;
            _includeProperties = 
                new List<Expression<Func<TEntity, object>>>();
        }

        public RepositoryQuery<TEntity> Filter(
            Expression<Func<TEntity, bool>> filter)
        {
            _filter = filter;
            return this;
        }

        public RepositoryQuery<TEntity> OrderBy(
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy)
        {
            _orderByQuerable = orderBy;
            return this;
        }

        public RepositoryQuery<TEntity> Include(
            Expression<Func<TEntity, object>> expression)
        {
            _includeProperties.Add(expression);
            return this;
        }

        public IEnumerable<TEntity> GetPage(
            int page, int pageSize, out int totalCount)
        {
            _page = page;
            _pageSize = pageSize;
            totalCount = _repository.Get(_filter).Count();

            return _repository.Get(
                _filter, 
                _orderByQuerable, _includeProperties, _page, _pageSize);
        }

        public IEnumerable<TEntity> Get()
        {
            return _repository.Get(
                _filter, 
                _orderByQuerable, _includeProperties, _page, _pageSize);
        }
    }

Addressing IRepository<TEntity> Extensibility

Well, what happens if we need extra methods a specific Repository? Meaning, how do we address “extensiblility” in our Repository? No problem, we have a couple of options here, we can simply inherit a Repository and add your own methods to it, or what I prefer, create extension methods e.g. extending IRepository (with some pseudo code for validating an address with UPS).

Repository.CustomerRepository.cs

    /// <summary>
    /// Extending the IRepository<Customer>
    /// </summary>
    public static class CustomerRepository
    {
        public static decimal GetCustomerOrderTotalByYear(
            this IRepository<Customer> customerRepository, 
            int customerId, int year)
        {
            return customerRepository
                .FindById(customerId)
                .Orders.SelectMany(o => o.OrderDetails)
                .Select(o => o.Quantity*o.UnitPrice).Sum();
        }

    /// <summary>
    /// TODO:
    /// This should really live in the Services project (Business Layer), 
    /// however, we'll leave it here for now as an example, and migrate
    /// this in the next post.
    /// </summary>
        public static void AddCustomerWithAddressValidation(
            this IRepository<Customer> customerRepository, Customer customer)
        {
            USPSManager m = new USPSManager("YOUR_USER_ID", true);
            Address a = new Address();
            a.Address1 = customer.Address;
            a.City = customer.City;

            Address validatedAddress = m.ValidateAddress(a);

            if (validatedAddress != null)
            customerRepository.InsertGraph(customer);
        }
    }

Great, now that we have our project nicely structured with the our generic implementation of the Unit of Work and Repository Pattern, let’s see how we can leverage this by wiring up a simple controller to show a list of customers.

To help us with this go ahead and NuGet the PagedList for MVC so we easily create a view with a paged grid.

5-10-2013 6-22-37 PM

Let’s create a CustomerController Index Action load a paged list of customers to hydrate a grid.


    public class CustomerController : Controller
    {
        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            var unitOfWork = new UnitOfWork();

            int totalCustomerCount;

            var customers =
                unitOfWork.Repository<Customer>()
                    .Query()
                    .Include(i => i.CustomerDemographics)
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            unitOfWork.Save();

            return View();
        }
    }

Next, let’s wire up the Index.cshtml view for our CustomerController Index Action.


@{
    ViewBag.Title = "Customers";
}

@using PagedList.Mvc;
@using PagedList;

<h2>Customers</h2>

<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />

<h2>List of Customers</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table style="width: 100%; padding: 10px;">
    <tr style="background-color: lightgray; padding: 10px;">
        <th>#</th>
        <th>Company
        </th>
        <th>Name
        </th>
        <th>Title
        </th>
        <th>Order Date
        </th>
    </tr>

    @foreach (var item in ViewBag.Customers)
    {
        <tr>
            <td>
                @Html.ActionLink(
                    "Edit", "Edit", new { id = item.CustomerID }) |

                @Html.ActionLink(
                    "Details", "Details", new { id = item.CustomerID }) |

                @Html.ActionLink(
                    "Delete", "Delete", new { id = item.CustomerID })
            </td>
            <td>
                @item.CompanyName
            </td>
            <td>
                @item.ContactName
            </td>
            <td>
                @item.ContactTitle
            </td>
            <td>
                @if (item.Orders.Count > 1)
                {
                    @item.Orders[1].OrderDate.ToShortDateString()
                }
            </td>
        </tr>
    }


    <tr>
        <td colspan="9">
            @Html.PagedListPager(
                (IPagedList)ViewBag.Customers, page => 
                    Url.Action("Index", new { page }))
        </td>
    </tr>

</table>


Go ahead and run our project to see our paged customers grid.

5-10-2013 6-46-30 PM

Abstracting the Complexity when Dealing with Entity Graphs

Another item I wanted to go over was insert and updating graphs with our Repository pattern. There are four use cases for inserting graphs, they are as follows.

5-10-2013 7-34-28 PM

To abstract the complexity and EF experience required, and how the DbContext manages graphs e.g to know to set the root entity state and how it affects other entities in the graph (e.g. updating the root entity in the graph, and existing entities in the graph are to be updated or deleted) we added a interface IOjectState that all of our entities will implement.

Entities.IObjectState.cs


namespace Data
{
    public interface IObjectState
    {
        ObjectState State { get; set; }
    }
}

Entities.ObjectState.cs (enum)


namespace Data
{
    public enum ObjectState
    {
        Unchanged,
        Added,
        Modified,
        Deleted
    }
}

These two classes will allow our development team to explicitly set the state of each of the entities in the graph when inserting or updating a graph. To make use of the classes we’ll need to extend the DbContext with a few methods, we’ll do this by creating extension methods.

Data.DbContextExtension.cs


    public static class DbContextExtension
    {
        public static void ApplyStateChanges(this DbContext dbContext)
        {
            foreach (var dbEntityEntry in dbContext.ChangeTracker.Entries())
            {
                var entityState = dbEntityEntry.Entity as IObjectState;
                if (entityState == null)
                    throw new InvalidCastException(
                        "All entites must implement " +
                        "the IObjectState interface, this interface " +
                        "must be implemented so each entites state" +
                        "can explicitely determined when updating graphs.");

                dbEntityEntry.State = ConvertState(entityState.State);
            }
        }

        private static EntityState ConvertState(ObjectState state)
        {
            switch (state)
            {
                case ObjectState.Added:
                    return EntityState.Added;
                case ObjectState.Modified:
                    return EntityState.Modified;
                case ObjectState.Deleted:
                    return EntityState.Deleted;
                default:
                    return EntityState.Unchanged;
            }
        }
    }

Now we will override the SaveChanges in our NorthwindContext to invoke the ApplyStateChanges method to synchronize our ObjectSate with EF’s EntityState, so that the context will know how to deal with each and every entity when dealing with entity graphs.

Data.NorthwindContext.SaveChanges()


        public override int SaveChanges()
        {
            this.ApplyStateChanges();
            return base.SaveChanges();
        }


Now when inserting, updating you can explicitly set the entities state, especially useful when dealing with graphs. This abstracts the skill-set of a developer using our Repository of having to know the what, when and how to set the state of entities in the graph in order for the context to update the graph and persist the graph correctly. Let’s take a look at an example of updating an existing Order and adding an OrderDetail item with an entity graph. Both these actions, are will be executed on the same graph, however notice that the action is different for both of the entity’s, one is updating and the other is adding, however we will only be invoking one method (IRepository.Update(TEntity entity) from our IRepository in one transaction.

So we’ll demonstrate and prove out updating an entity graph with our UnitOfWork implementation in these steps.

Code Snippet from LinqPad, notice how we are explicitly setting each of the entities state in the entity graph.


var unitOfWork = new UnitOfWork(this);

var orderId = 10253;

unitOfWork
	.Repository<Order>()
	.Query()
	.Include(t => t.Customer)
	.Filter(t=> t.OrderID == orderId)
	.Get().Dump();

var order = unitOfWork
	.Repository<Order>()
	.FindById(orderId);

unitOfWork
	.Repository<OrderDetail>()
	.Query()
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();

order.ShipName = "Long Le";
order.State = ObjectState.Modified;

order.OrderDetails.Add(
	new OrderDetail{
		ProductID = 2,
		UnitPrice = 10,
		Quantity = 2,
		Discount = 1,
		State = ObjectState.Added
	}
);


unitOfWork.Repository<Order>()
	.Update(order);

unitOfWork.Save();

new UnitOfWork(this)
	.Repository<Order>()
	.Query()
	.Include(t => t.Customer)
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();
	
new UnitOfWork(this)
	.Repository<OrderDetail>()
	.Query()
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();
		

Entity Graph Update Scenario

  1. Query the Order table, make note of the ShipName value.
  2. Query the OrderDetail table, make not there are only three (3) items, that belong to the same Order.
  3. Update the ShipName value in the Order.
  4. Add an OrderDetail to the Order.

5-11-2013 4-13-23 PM

(click image to enlarge)

Presto, we were able to successfully update an existing Order and add a new OrderDetail via an entity graph with one transaction using one method. Now, we can absolutely do this using EF out of the box, however, our goal here is was to abstract the complexity and skill set required from a developer in regards to EF specially how do deal with the DbContext in order to make this happen as well as obviously still support working with graphs through our IRepository implementation.

There you have it, and extensible genericized implementation of the UoW and Repository pattern with EF in MVC. In the next blog post, we’ll add DI & IoC to this solution and introduce the Services layer, this layer will house all of our business logic and rules. We will also implement the Services layer in a way, where we don’t violate our Unit of Work pattern, meaning all the work done in our Repository and Services are executed under one single instance the DbContext per page request.

Happy Coding..! 🙂

Download sample: https://genericunitofworkandrepositories.codeplex.com