Using LinqPad to Query & Troubleshoot Your Custom Entity Framework DbContext, Unit of Work & Repository Pattern

I received a couple of questions on how to use LinqPad to run queries through the Unit of Work and Repository pattern implementations from my previous blog. With that being said, here’s a blog post on how to accomplish this since I wasn’t able to find any good documentation on this either.

For anyone that has not had the opportunity to work with LinqPad, this is definite a must have, as part of your development toolkit. It’s great to hash out some quick code, PoC’s, and troubleshooting EF queries. LinqPad is awesome, especially when working with a large solution, so that you can avoid lengthy build times and compilations just to test out a small block of code. You can quickly and easily test and verify your code and/or queries first in LinqPad, before building it into your actual project.

Download the source code (https://skydrive.live.com/redir?resid=949A1C97C2A17906!5536&authkey=!APbwDGYDnBjHJPE) from my previous blog that uses EF5 and make sure everything compiles.

Note: Although in the original blog post I used the Alpha release of EF6, I’ve ran into some intermittent issues with it using LinqPad, so for purposes of this post we’ll stick the release version, EF5.

Launch Linqpad and perform the following steps:

  1. Add a new Connection
    6-11-2013 5-01-17 PM

  2. Add a Typed Data Context Connection
    6-11-2013 5-03-33 PM

  3. Browse to the Data.dll in the Web\Bin directory
    6-11-2013 5-07-31 PM

  4. Browse to the Web.config file of the Web project
    6-11-2013 5-09-26 PM

  5. Verify that the Northwind DbContext has been reflected on by LinqPad
    6-11-2013 5-10-21 PM

  6. Navigate to Query Properties dialog window
    6-11-2013 5-12-01 PM
  7. Add all the following references so that we can use the Unit of Work and Repository assemblies
    6-11-2013 5-13-48 PM

  8. NuGet Entity Framework Version 5.0.0
    6-11-2013 5-15-06 PM

  9. Verify that your Query Properties has the following references
    6-11-2013 5-16-12 PM
  10. Add the following Namespace Imports
    6-11-2013 5-17-09 PM

  11. Change your Query Language to C# Program and select NorthwindContext in Data.dll as your Connection.
    6-11-2013 5-18-59 PM
  12. Code up a LinqPad query using the Unit of Work and Repository implementation and out the results using the LinqPad’s Dump() extension method.
    
    void Main()
    {
    	int? page= null;
    	var pageNumber = page ?? 1;
    	const int pageSize = 20;
    	int totalCustomerCount;
    	var unitOfWork = new UnitOfWork();
    
    	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);	
    			
    	customers.Dump();
    }
    
    
  13. You should see your results returned through our Unit of Work and Repository implementation
    6-11-2013 5-24-15 PM

  14. As well as the generated SQL from EF
    6-11-2013 5-25-24 PM

Happy Coding…! 🙂

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

Wrapping the Ninject Kernel with ServiceLocator

I was a big fan of using Unity or Mef for IoC in my apps, we used Prism heavily in one of my past projects with Silverlight. Prism offered a IoC with your choice of Unity or Mef for your container as well as very good approach to building a scalable application with the notion of Prism Modules.

I recently came on board to a project extensively using Ninject for our MVC3 application. Ninject has the notion of a Kernel which is pretty much how you access your container of registered or bound instances.

In the event where you would ever change out or switch your IoC implementation or choice of frameworks, a nice wrapper, that wrapped your method of accessing your container would be great. You can in theory switch out your IoC (container) with Mef, Unity, Sprint.NET, AutoFac, Castle Windsor, or any other IoC framework with minimal refactoring (here’s a great list of some popular IoC frameworks from Scott Hanselman). 

With a little research I found that Ninject has a ServiceLocator adapter that you can wire up when you setup your Kernel. With this wired up you can access your Ninject container with the standard Microsoft ServiceLocator, which is also a widely used pattern.

For this demonstration we are just going to use the MVC3 application used from my previous blog: http://blog.longle.net/2012/02/15/inject-ioc-my-mvc3-application-in-less-than-5-minutes/

  1. Right click your references folder and click “Manage NuGet Packages”
  2. Search for ServiceLocator, and install the CommonServiceLocator.NinjectAdapter Package
  3. You should now see the NinjectAdapter reference added
  4. Let’s wire this up now, we will visit the Global.asax.cs file where we setup and initialized our Kernel (container), here’s where we an register the NinjectServiceLocator Adapter with Microsoft.Practices.ServiceLocation.ServiceLocator interface.
    
            protected void Application_Start()
            {
                RegisterMyDependencyResolver();            
                AreaRegistration.RegisterAllAreas();
                RegisterGlobalFilters(GlobalFilters.Filters);
                RegisterRoutes(RouteTable.Routes);
            }
    
            private void RegisterMyDependencyResolver()
            {
                var standardKernel = new StandardKernel();
                standardKernel.Bind<IHelloWorldService>().To<HelloWorldService>();
                ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(standardKernel));
                DependencyResolver.SetResolver(new MyDependencyResolver(standardKernel));
            }
    
    
  5. So the first place I wanted to use the ServiceLocator was in our MyDependendencyResolver class, where the MVC runitme routes all request get instances for all your registered or bound interfaces. What happens here is that when the MVC runtime requests for a registered instance of a specific interface and your container does not have one, MVC expects a your IoC container to return a null value and at this point MVC will fallback and attempt to return the default instance.

    For example if the MVC runtime requests for an IControllerFactory and you didn’t setup a binding or registration for this interface the MVC runtime will just return a DefaultControllerFactory in this case. The Ninject Kernel will automatically return null in this case.

    However when using the ServiceLocator interface, there is not a TryGet method like the Ninject Kernel offers when requesting instance, the TryGet method will actually scan the container for any registrations for a given interface and if it doesn’t find one it will return null for you.

    So I have to admit there wasn’t a way to really elegantly handle this. So to mimic this behaivor, which is returning a null when we weren’t able to find any registrations with the ServiceLocator, I had to wrap they request and catch the Microsoft.Practices.ServiceLocation.ActivationException, and if this exception was caught then we would return null so that the MVC runtime could take over and return default instances e.g. when requesting the IControllerFactory, ServiceLocator would return null, and MVC would take over and return the DefaultControllerFactory.

    Here’s the exception before wrapping the request:

    
        public class MyDependencyResolver : IDependencyResolver
        {
            public object GetService(Type serviceType)
            {
                    return ServiceLocator.Current.GetInstance(serviceType);
            }
    
            public IEnumerable<object> GetServices(Type serviceType)
            {
                    return ServiceLocator.Current.GetAllInstances(serviceType);
            }
        }
    
    

  6. After wrapping the request to our container and returning null after scanning our container and not finding a registered instance for that interface, in our case the IControllerFactory.
    
        public class MyDependencyResolver : IDependencyResolver
        {
            public object GetService(Type serviceType)
            {
                try
                {
                    return ServiceLocator.Current.GetInstance(serviceType);
                }
                catch (Microsoft.Practices.ServiceLocation.ActivationException ex)
                {
                    return null;
                }
            }
    
            public IEnumerable<object> GetServices(Type serviceType)
            {
                try
                {
                    return ServiceLocator.Current.GetAllInstances(serviceType);
                }
                catch (Microsoft.Practices.ServiceLocation.ActivationException ex)
                {
                    return null;
                }
            }
        }
    
    

    Obviously we could create a two extension methods for ServiceLocator maybe TryGet and TryGetAll, but in the interest of time we’ll skip that for now.

    Note, you can always use ServiceLocator everywhere else in your application when requesting for instance(s) for a given interface from your Kernel and leave our former implementation of MyDependencyResolver accessing the Ninject Kenerl directly if you are uncomfortable with wrapping it with the try/catch block to return null, so that the MVC runtime can fallback and return default instances e.g. IControllerFactory -> DefaultControllerFactory.

    Again, not the most elegant way, however when doing a deep dive on the TryGet method from the Ninject Kernel with Reflector I notice that we weren’t to far off from what Ninject was actually doing here.

  7. If you look at the GetValue method that we reflected on (which is what eventually get’s called by the Ninject’s _kernel.TryGet method, notice the return statement ending with the lambda expression SingleOrDefault()
    
    protected virtual object GetValue(Type service, IContext parent)
    {
        Ensure.ArgumentNotNull(service, "service");
        Ensure.ArgumentNotNull(parent, "parent");
        IRequest request = parent.Request.CreateChild(service, parent, this);
        request.IsUnique = true;
        return parent.Kernel.Resolve(request).SingleOrDefault<object>();
    }
    
    

    which returns null if a registration was not found for that interface in our Ninject container.

    Obviously wrapping our request and catching the ActivationException, we are swallowing the exception, which could create some difficulties in debugging true exceptions where things weren’t wired up correctly for Ninject to bind and activate instances to return to us.

  8. Now let’s see do a quick demonstration on using the ServiceLocator pattern other than in our MyDependencyResolver class. Let’s revisit the HomeController where we were orginall injected the IHelloWorldService in the constructor. An alternative way here is we can manually get this injected by requesting it with ServiceLocator.
    Before:
    
        public class HomeController : Controller
        {
            private readonly IHelloWorldService _helloWorldService;
    
            public HomeController(IHelloWorldService helloWorldService)
            {
                _helloWorldService = helloWorldService;
            }
    
            public ActionResult Index()
            {
                ViewBag.Message = _helloWorldService.Hello(@"Welcome to ASP.NET MVC!");
                return View();
            }
    
            public ActionResult About()
            {
                return View();
            }
        }
    
    

    After:

    
        public class HomeController : Controller
        {
            private readonly IHelloWorldService _helloWorldService;
    
            public HomeController()
            {
                _helloWorldService = ServiceLocator.Current.GetInstance<IHelloWorldService>();
            }
    
            public ActionResult Index()
            {
                ViewBag.Message = _helloWorldService.Hello(@"Welcome to ASP.NET MVC!");
                return View();
            }
    
            public ActionResult About()
            {
                return View();
            }
        }
    
    

    Now it’s really preference whether you want the MVC runtime to use our MyDependencyResolver in conjunction with Ninject to automagically figure out what needs to be injected like in our [before] case which was injecting the IHellowWorldService in the constructor of HomeController, or manually requesting it using ServiceLocator.

    Again I don’t see a wrong or right in eithier way, it’s just really preference, I prefer going with our before case where we let MyDependencyResolver and Ninject figure out what, when and where things automagically need to be injected, however I just wanted to demonstrate abstracting Ninject’s Kernel with ServiceLocator if you wanted to have the flexibility of easiliy swapping out our choice of IoC frameworks with mininmal refactoring or code change. 🙂

Download sample application: https://skydrive.live.com/redir.aspx?cid=949a1c97c2a17906&resid=949A1C97C2A17906!371&parid=949A1C97C2A17906!361

Quick Review on the Strategy Pattern…!

So you have a set of similar classes where you want to encapsulate a family of related algorithms. Each the classes have different variations of a similar algorithm or business rules and they need a way to evolve separately from the classes that are using (consuming) them. In this fictitious example we are a phone retailer, could be a system we use online as well as the POS system that is used at an actual brick and mortar store. Now when selling phones you have to order phones from different distributors or manufactures, each manufacture having different business rules and services you may need to call in order to for the manufacture’s distribution center to fulfill your order. The Strategy Pattern comes in handy here so that we can effectively manage these different types of custom implementations for ordering from all these different types of manufactures while not having to rebuild, or compile our OrderService every time we start doing business with new phone manufacture. Last but not least it makes managing our code with all these different manufactures a whole heck of a lot easier…!

So in this example our manufactures will be Apple, HTC, Nokia, and Sony. Each will have their own processes and business rules to adhere to when placing order and getting your phone order fulfilled for your customers.

Our domain model (pretty self-explanatory, so I won’t will dive into any details on this)

1-30-2012 6-07-40 PM

Let’s take a look at what are implementation would like in order to handle all the different manufactures in our domain before implementing the Strategy Pattern.

So we have our OrderService, a class that handles all the heavy lifting for ordering from any given manufacture we do business with. Each case in our switch statement having custom implementation for that given manufacture, I’ve kept this pretty simple to get the point across however in the real world you could probably expect to do specific validation, business rules, executing different back-end services, etc… for a given manufacture.

VSProject: BeforeStrategyPattern, Class: OrderService.cs

      

    public class OrderService
    {
        public ManufactureInvoice OrderProduct(Product product)
        {
            switch (product.Manufacture)
            {
                case Manufacture.Sony:
                    // call Sony webservices, etc...
                    return new ManufactureInvoice
                    {
                        Cost = product.Cost,
                        EstimatedArrivalDate = DateTime.Now.AddDays(5),
                        EstimatedShippedDate = DateTime.Now,
                        Tax = product.Cost * .07M,
                        Manufacture = Manufacture.Sony
                    };

                case Manufacture.Apple:
                    // call Apple webservices, etc...
                    return new ManufactureInvoice
                    {
                        Cost = product.Cost,
                        EstimatedArrivalDate = DateTime.Now.AddDays(5),
                        EstimatedShippedDate = DateTime.Now,
                        Tax = product.Cost * .07M,
                        Manufacture = Manufacture.Apple
                    };

                case Manufacture.Nokia:
                    // call Nokia webservices, etc...
                    return new ManufactureInvoice
                    {
                        Cost = product.Cost,
                        EstimatedArrivalDate = DateTime.Now.AddDays(5),
                        EstimatedShippedDate = DateTime.Now,
                        Tax = product.Cost * .07M,
                        Manufacture = Manufacture.Nokia
                    };

                case Manufacture.Htc:
                    // call Htc webservices
                    return new ManufactureInvoice
                    {
                        Cost = product.Cost,
                        EstimatedArrivalDate = DateTime.Now.AddDays(5),
                        EstimatedShippedDate = DateTime.Now,
                        Tax = product.Cost * .07M,
                        Manufacture = Manufacture.Htc
                    };

                default:
                    throw new UnknownManufactureException();
            }
        }
    }


So just by looking at this class we can already see that if we were to making any changes to any of the implementation for any of these distributors we would have to making changes to this class because of the tight coupling of the OrderService and our ordering algorithms for each individual manufactures.

Let’s see what the Strategy Pattern can do for us, first we are going to add a few an interface and a few class which will implement this interface (VS Project: AfterStrategyPatternA)

Each of the classes that implement the IManufactureOrderStrategy interface which will be an ordering strategy for that manufacture, where you could call different services, business rules, validation, etc… They all related, in which they all order a phone from a manufacture and fulfill our order, however the only difference is they way they may behave for a given manufacture. Now we will make changes to our OrderService class where our clunky switch statement was earlier

VS Project: AfterStrategyPatternA, Class: OrderService.cs


    class OrderService
    {
        public readonly IOrderingStrategy _manufactureOrderingStrategy;

        public OrderService(IOrderingStrategy manufactureOrderingStrategy)
        {
            _manufactureOrderingStrategy = manufactureOrderingStrategy;
        }

        public ManufactureInvoice OrderProductFromManufacture(Product product)
        {
            return _manufactureOrderingStrategy.OrderProduct(product);
        }
    }

As you can see, instead of the OrderService containing the actual business logic and implementation for ordering with each of our manufactures, we are now passing this into the OrderService class. Let’s take a quick look on how what the consumer code would look
like using our new decoupled OrderingService.

VS Project: AfterStrategyPatternA, Class: OrderProductFromManufacture_Test.cs


    [TestClass]
    public class OrderProductFromManufacture_Test
    {
        [TestMethod]
        public void When_Manufacture_is_From_Apple()
        {
            var _order = MockOrderPipeline.CreateOrder();
            
            var appleProduct = _order.OrderDetails
                .Where(o => o.Product.Manufacture == Manufacture.Apple)
                .Single()
                .Product;

            var appleOrderStrategy = new AppleOrderStrategy();
            var manufactureOrderingService = new OrderService(appleOrderStrategy);
            var manufactureInvoice = manufactureOrderingService.OrderProductFromManufacture(appleProduct);

            Assert.AreEqual(manufactureInvoice.Manufacture, Manufacture.Apple);
        }

        [TestMethod]
        public void When_Manufacture_is_From_Htc()
        {
            var _order = MockOrderPipeline.CreateOrder();
            var htcProductFromOrder = _order.OrderDetails
                .Where(o => o.Product.Manufacture == Manufacture.Htc).Single().Product;

            var htcOrderStrategy = new HtcOrderStrategy();
            var manufactureOrderingService = new OrderService(htcOrderStrategy);
            var manufactureInvoice = manufactureOrderingService.OrderProductFromManufacture(htcProductFromOrder);

            Assert.AreEqual(manufactureInvoice.Manufacture, Manufacture.Htc);
        }

        [TestMethod]
        public void When_Manufacture_is_From_Nokia()
        {
            var _order = MockOrderPipeline.CreateOrder();
            var nokiaProductFromOrder = _order.OrderDetails.Where(o => o.Product.Manufacture == Manufacture.Nokia).Single().Product;

            var nokiaOrderStrategy = new NokiaOrderStrategy();
            var manufactureOrderingService = new OrderService(nokiaOrderStrategy);
            var manufactureInvoice = manufactureOrderingService.OrderProductFromManufacture(nokiaProductFromOrder);

            Assert.AreEqual(manufactureInvoice.Manufacture, Manufacture.Nokia);
        }

        [TestMethod]
        public void When_Manufacture_is_From_Sony()
        {
            var _order = MockOrderPipeline.CreateOrder();
            var sonyProductFromOrder = _order.OrderDetails.Where(o => o.Product.Manufacture == Manufacture.Sony).Single().Product;

            var sonyOrderStrategy = new SonyOrderStrategy();
            var manufactureOrderingService = new OrderService(sonyOrderStrategy);
            var manufactureInvoice = manufactureOrderingService.OrderProductFromManufacture(sonyProductFromOrder);

            Assert.AreEqual(manufactureInvoice.Manufacture, Manufacture.Sony);
        }
    }

Note that for each of these calls we are passing a custom implementation (e.g. AppleOrderStrategy, HtcOrderStrategy, NokiaOrderStrategy, SonyOrderStrategy) of for each of the manufactures who all implement the IOrderingStategy interface. So now our OrderingService class adheres to the “open close principle”, where our OrderingService should be open for extension, but closed for modification.

Finally, let’s take a look a different form of using the Strategy Pattern using Funcs, delegates and lambdas (VS Project: AfterStrategyPatternB, class: OrderProductFromManufacture_Test).

First let’s take a quick look at our enhanced OrderingService.

VS Project: AfterStrategyPatternB, Class: OrderService.cs


    public class OrderService
    {
        public ManufactureInvoice OrderProduct(Product product, 
            Func<Product, ManufactureInvoice> orderingStrategy)
        {
            return orderingStrategy(product);
        }
    }

Notice how we are now passing in a generic func vs. a class that, and the func expects the Product to be ordered to be passed into it where it will then return a ManufactureInvoice for the product that was ordered and to be fulfilled.

Now let’s take a the new OrderService consuming code, notice how we can now still pass in our implementation as long as we are compliant with the generic func parameter of our OrderServce.OrderProduct method. We can somewhat think of the generic func as our new contract, contract meaning we have to pass in a Product entity and we have to return a ManufactureInvoice after we have completed the ordering process.

VS Project: AfterStrategyPatternB, Class: OrderProductFromManufacture_Test.cs


    [TestClass]
    public class OrderProductFromManufacture_Test
    {        
        [TestMethod]
        public void When_Manufacture_is_Apple()
        {
            // using lambda expression
            Func<Product, ManufactureInvoice> appleStrategy = product => 
                new ManufactureInvoice { 
                    Cost = product.Cost, 
                    EstimatedArrivalDate = DateTime.Now.AddDays(5), 
                    EstimatedShippedDate = DateTime.Now, 
                    Tax = product.Cost * .07M, 
                    Manufacture = Manufacture.Apple };

            var _order = MockOrderPipeline.CreateOrder();

            var appleProduct = _order.OrderDetails
                .Where(o => o.Product.Manufacture == Manufacture.Apple)
                .Single()
                .Product;

            OrderService orderService = new OrderService();
            orderService.OrderProduct(appleProduct, appleStrategy);
        }

        [TestMethod]
        public void When_Manufacture_is_Sony()
        {
            // using delegate
            Func<Product, ManufactureInvoice> sonyStrategy = 
                delegate(Product product) { return new ManufactureInvoice { 
                    Cost = product.Cost, 
                    EstimatedArrivalDate = DateTime.Now.AddDays(5), 
                    EstimatedShippedDate = DateTime.Now, 
                    Tax = product.Cost * .07M, 
                    Manufacture = Manufacture.Sony }; };

            var _order = MockOrderPipeline.CreateOrder();

            var sonyProduct = _order.OrderDetails
                .Where(o => o.Product.Manufacture == Manufacture.Sony)
                .Single()
                .Product;

            OrderService orderService = new OrderService();
            orderService.OrderProduct(sonyProduct, sonyStrategy);
        }

        [TestMethod]
        public void When_Manufacture_is_Nokia()
        {            
            var _order = MockOrderPipeline.CreateOrder();
            
            // using inline lambda expression (fluent)
            var sonyProduct = _order
                .OrderDetails
                .Where(o => o.Product.Manufacture == Manufacture.Sony)
                .Single()
                .Product;

            OrderService orderService = new OrderService();

            orderService.OrderProduct(sonyProduct, product =>
            {
                return new ManufactureInvoice { 
                    Cost = product.Cost, 
                    EstimatedArrivalDate = DateTime.Now.AddDays(5), 
                    EstimatedShippedDate = DateTime.Now, 
                    Tax = product.Cost * .07M, 
                    Manufacture = Manufacture.Sony };
            });
        }

        [TestMethod]
        public void When_Manufacture_is_Htc()
        {
            var _order = MockOrderPipeline.CreateOrder();
            
            // using anonymous method
            var htcProduct = _order
                .OrderDetails
                .Where(o => o.Product.Manufacture == Manufacture.Htc)
                .Single()
                .Product;

            OrderService orderService = new OrderService();
            orderService.OrderProduct(htcProduct, OrderProductFromHtc);
        }

        private ManufactureInvoice OrderProductFromHtc(Product product)
        {
            // e.g. invoke htc webservices, invoke order services, invoke dropshipment services, publish events to service
            return new ManufactureInvoice { 
                Cost = product.Cost, 
                EstimatedArrivalDate = DateTime.Now.AddDays(5), 
                EstimatedShippedDate = DateTime.Now, 
                Tax = product.Cost * .07M, 
                Manufacture = Manufacture.Htc };
        }
    }


Download the Strategy Pattern sample VS Solution: https://skydrive.live.com/embed?cid=949A1C97C2A17906&resid=949A1C97C2A17906%21369&authkey=AD0Eu1b0USnB5do