Category Archives: Programming

Specification Pattern In Entity Framework 4 Revisited

After the post Entity Framework 4 POCO, Repository and Specification Pattern was published for a while, there have been quite a few of positive comments from readers. At first, I thought that this piece of code should have been used as a prototype to demonstrate the implementation of EF POCO, the Repository and Specification pattern. I known it is not the optimized piece of code to everyone and that if there was suggestion for improvement, I would leave to reader as I thought once they understood the design idea, they could extend/change/use the API in anyway they want.

However, there are also some comments concerning about the way the Specification pattern is applied which might cause the BIG performance problem when used that I was not aware of. Even I am using this API in my current work but it’s a shame that I rarely use Specification to query the data but the other methods are enough for me.

For your information, here are the extracted comments from Jon & Buu (many thanks :)) which pointed out the problem:

Jon: Linq to Entities uses expressions to build the SQL that will be executed on the database server. If you use the specification pattern as designed above, i.e., without expressions, the generated SQL is never impacted. Instead, EF will generate “SELECT * FROM Table,” returning all rows. From there the specification pattern kicks in and filters the data in memory. Your test passed because you got the right result, but not in the right way. it would never work in a real would scenario.”

Buu:  …the cause of the issue as Jon observed is because the method (IsSatisfiedBy) of Specification is fed into the Where method of the query object. That results in LINQ-2-EF loading all records to memory objects and then filter those objects using the passed in method. That’s a huge performance hit.

To fix the issue, you should feed into the Where method an instance of Expression so that the Where overload in IQueryable is invoked (instead of the one in IEnumerable). The Specification already stores an instance of Expression, so the code change should be straightforward. However, since not all expression operations are supported by LINQ-2-EF, you might end up breaking some existing code. Be warned…”

I verified the problem with Entity Framework Profiler and I have to say the problem is there. Here are some tests I made to retrieve a product by name, and also the results from the profiler:

Use standard lambda expression:

private void FindProductByName()
{
    IEnumerable<Product> products = productRepository.Find<Product>(p => p.Name == "Windows XP Professional");
    Assert.AreEqual(1, products.Count());
}

The output from the profiler

EF generated the correct sql and returned the expected result, no thing wrong with this.

Use specification

private void FindBySpecification()
{
    Specification<Product> specification = new Specification<Product>(p => p.Name == "Windows XP Professional");
    IEnumerable<Product> products = productRepository.Find<Product>(specification);
    Assert.AreEqual(1, products.Count());
}

The output from the profiler

As you can see there is a problem with using specification to retrieve a product in which EF loads all the products from the database, then perform filtering a product against the whole set of products in-memory. If the number of products is huge, it really is an issue since the query is not efficient at all.

This is because the specification pattern is implemented incorrectly. To fix it, I change the specification contract as the following:

public interface ISpecification<TEntity>
{
    TEntity SatisfyingEntityFrom(IQueryable<TEntity> query);

    IQueryable<TEntity> SatisfyingEntitiesFrom(IQueryable<TEntity> query);
}

And the implementation of some generic repository’s methods which accepts a specification are as following:

public class GenericRepository : IRepository
{
    // other code...

    public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
    {
        var entityName = GetEntityName<TEntity>();
        return ObjectContext.CreateQuery<TEntity>(entityName);
    }

    public TEntity FindOne<TEntity>(ISpecification<TEntity> criteria) where TEntity : class
    {
        return criteria.SatisfyingEntityFrom(GetQuery<TEntity>());
    }

    public IEnumerable<TEntity> Find<TEntity>(ISpecification<TEntity> criteria) where TEntity : class
    {
        return criteria.SatisfyingEntitiesFrom(GetQuery<TEntity>());
    }

    // other code...
}

The implementation of a simple specification is straightforward.

public class Specification<TEntity> : ISpecification<TEntity>
{
    public Specification(Expression<Func<TEntity, bool>> predicate)
    {
        Predicate = predicate;
    }

    public TEntity SatisfyingEntityFrom(IQueryable<TEntity> query)
    {
        return query.Where(Predicate).SingleOrDefault();
    }

    public IQueryable<TEntity> SatisfyingEntitiesFrom(IQueryable<TEntity> query)
    {
        return query.Where(Predicate);
    }

    public Expression<Func<TEntity, bool>> Predicate;
}

Here is the output of the profiler with the new specification implementation:

As you can see EF now generates the expected sql and returns expected result as well, very efficient.

What about the composite specification?

If you already read the previous post, you should have known that the composite specification was being used to chain the specifications. With the new implementation of specification, the composite specification implementation also needs to change. The technique being applied here is to combine the lambda expression (or predicate) of each specification (left and right side of a composite specification) to create a new lambda expression then this new lambda expression is fed to the IQuerable object for querying.

Here is the code of the extension method of lambda expression which is mostly inspired from here:

public static class ExpressionExtension
{
    public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
    {
        // build parameter map (from parameters of second to parameters of first)
        var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

        // replace parameters in the second lambda expression with parameters from the first
        var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);

        // apply composition of lambda expression bodies to parameters from the first expression
        return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
    }

    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
    {
        return first.Compose(second, Expression.And);
    }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
    {
        return first.Compose(second, Expression.Or);
    }
}

And here is the implementation of the composite specification:

public class AndSpecification<TEntity> : CompositeSpecification<TEntity>
{
    public AndSpecification(Specification<TEntity> leftSide, Specification<TEntity> rightSide)
        : base(leftSide, rightSide)
    {
    }

    public override TEntity SatisfyingEntityFrom(IQueryable<TEntity> query)
    {
        return SatisfyingEntitiesFrom(query).FirstOrDefault();
    }

    public override IQueryable<TEntity> SatisfyingEntitiesFrom(IQueryable<TEntity> query)
    {
        return query.Where(_leftSide.Predicate.And(_rightSide.Predicate));
    }
}

public class OrSpecification<TEntity> : CompositeSpecification<TEntity>
{
    public OrSpecification(Specification<TEntity> leftSide, Specification<TEntity> rightSide)
        : base(leftSide, rightSide)
    {
    }

    public override TEntity SatisfyingEntityFrom(IQueryable<TEntity> query)
    {
        return SatisfyingEntitiesFrom(query).FirstOrDefault();
    }

    public override IQueryable<TEntity> SatisfyingEntitiesFrom(IQueryable<TEntity> query)
    {
        return query.Where(_leftSide.Predicate.Or(_rightSide.Predicate));
    }
}

The test code to find product by name and price which uses the AndSpecification

private void FindByAndCompositeSpecification()
{
    IEnumerable<Product> products = productRepository.Find<Product>(
        new Specification<Product>(p => p.Price < 100).And(new Specification<Product>(p => p.Name == "Windows XP Professional")));
    Assert.AreEqual(1, products.Count());
}

The output from the profiler:

The test code to find product which applies the OrSpecification:

private void FindByOrCompositeSpecification()
{
    IEnumerable<Product> products = productRepository.Find<Product>(
        new Specification<Product>(p => p.Price < 100).Or(new Specification<Product>(p => p.Name == "Windows XP Professional")));
    Assert.AreEqual(2, products.Count());
}

The output from the profiler:

The problem is solved!

The updated source code can be downloaded here.

Once again, comments are welcome.

Advertisements

Entity Framework 4 POCO, Repository and Specification Pattern

Updated (25 Aug 2010): There are some concerns from Jon and Buu about the performance hit when implementing the specification pattern follow the way that this post shows. That said, the implementation of this pattern has been updated and you can read it through at Specification Pattern In Entity Framework 4 Revisited
Updated: The post has a small update with the new release of Entity Framework Feature Community Technology Preview 4 (CTP4) in which the ObjectContextBuilder class changed its base class from ContextBuilder<T> to ModelBuilder. The source code has also been upgraded to CTP4 version. Note that to successfully compile the code, you have to install the EF CTP4 version which can be downloaded here.
After a decent period using NHibernate & SharpArchitecture to build .NET application, I eventually have a chance to work with Entity Framework (EF) in recent project. The client wants to leverage MS technologies as much as possible instead of some OSS frameworks to avoid learning curves and maintenance issues that might occurs later on. No matter what the decision is good or bad which some of you might agree or disagree, I am being put in a position to build the application with the team. And just because I have had some experience on building data access mechanism (mostly with ADO.NET and NHibernate), this more or less leads me to work with this data access layer again. 

Just like those who are going to work with a new technology, I started digging into EF by reading related books, hunting the web to find good articles and blog posts mentioning about building data access on top of EF. Since I have worked with NHibernate and also use Repository Pattern  to build the data access layer, the keywords entered Google should include: “Entity Framework”, “Entity Framework Repository”, “Entity Framework vs. NHibernate”, “Entity Framework POCO and Repository Pattern”  blah blah blah. Luckily I found quite a few of good posts (these will be listed as source of references at the end of this post).

With some sources of reference in hand, I started to build the data access layer using EF. But before talking about how I build it, here is a set of design patterns I want to apply: Repository, Unit of Work, and Specification. Since I also want to use POCOs instead of objects auto-generated by Visual Studio so this, once again, leads me to looking for the technique to write mapping stuff, and I found that it is also very easy.

Repository

Repository is defined as “an abstraction that provides us with persistence ignorance and a separation of concerns where the responsibility of persisting domain objects is encapsulated by the Repository that  leaving the domain objects to deal entirely with the domain model and domain logic.”

The contract for a repository contains operations to perform CRUD and also for querying entity objects.  The general technique is using .NET generic to build the Repository, the code below depicts the contract of repository:

public interface IRepository<TEntity> : IDisposable where TEntity : class
{
    IQueryable<TEntity> GetQuery();
    IEnumerable<TEntity> GetAll();
    IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
    TEntity Single(Expression<Func<TEntity, bool>> predicate);
    TEntity First(Expression<Func<TEntity, bool>> predicate);
    void Add(TEntity entity);
    void Delete(TEntity entity);
    void Attach(TEntity entity);
    void SaveChanges();
    void SaveChanges(SaveOptions options);
}

And the common implementation:

/// <summary>
/// A generic repository for working with data in the database
/// </summary>
/// <typeparam name="T">A POCO that represents an Entity Framework entity</typeparam>
public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
    /// <summary>
    /// The context object for the database
    /// </summary>
    private ObjectContext _context;

    /// <summary>
    /// The IObjectSet that represents the current entity.
    /// </summary>
    private IObjectSet<TEntity> _objectSet;

    /// <summary>
    /// Initializes a new instance of the GenericRepository class
    /// </summary>
    /// <param name="context">The Entity Framework ObjectContext</param>
    public GenericRepository(ObjectContext context)
    {
        _context = context;
        _objectSet = _context.CreateObjectSet<TEntity>();
    }

    /// <summary>
    /// Gets all records as an IQueryable
    /// </summary>
    /// <returns>An IQueryable object containing the results of the query</returns>
    public IQueryable<TEntity> GetQuery()
    {
        return _objectSet;
    }

    /// <summary>
    /// Gets all records as an IEnumberable
    /// </summary>
    /// <returns>An IEnumberable object containing the results of the query</returns>
    public IEnumerable<TEntity> GetAll()
    {
        return GetQuery().AsEnumerable();
    }

    /// <summary>
    /// Finds a record with the specified criteria
    /// </summary>
    /// <param name="predicate">Criteria to match on</param>
    /// <returns>A collection containing the results of the query</returns>
    public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
    {
        return _objectSet.Where<TEntity>(predicate);
    }

    /// <summary>
    /// Gets a single record by the specified criteria (usually the unique identifier)
    /// </summary>
    /// <param name="predicate">Criteria to match on</param>
    /// <returns>A single record that matches the specified criteria</returns>
    public TEntity Single(Expression<Func<TEntity, bool>> predicate)
    {
        return _objectSet.Single<TEntity>(predicate);
    }

    /// <summary>
    /// The first record matching the specified criteria
    /// </summary>
    /// <param name="predicate">Criteria to match on</param>
    /// <returns>A single record containing the first record matching the specified criteria</returns>
    public TEntity First(Expression<Func<TEntity, bool>> predicate)
    {
        return _objectSet.First<TEntity>(predicate);
    }

    /// <summary>
    /// Deletes the specified entitiy
    /// </summary>
    /// <param name="entity">Entity to delete</param>
    /// <exception cref="ArgumentNullException"> if <paramref name="entity"/> is null</exception>
    public void Delete(TEntity entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }

        _objectSet.DeleteObject(entity);
    }

    /// <summary>
    /// Adds the specified entity
    /// </summary>
    /// <param name="entity">Entity to add</param>
    /// <exception cref="ArgumentNullException"> if <paramref name="entity"/> is null</exception>
    public void Add(TEntity entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }

        _objectSet.AddObject(entity);
    }

    /// <summary>
    /// Attaches the specified entity
    /// </summary>
    /// <param name="entity">Entity to attach</param>
    public void Attach(TEntity entity)
    {
        _objectSet.Attach(entity);
    }

    /// <summary>
    /// Saves all context changes
    /// </summary>
    public void SaveChanges()
    {
        _context.SaveChanges();
    }

    /// <summary>
    /// Saves all context changes with the specified SaveOptions
    /// </summary>
    /// <param name="options">Options for saving the context</param>
    public void SaveChanges(SaveOptions options)
    {
        _context.SaveChanges(options);
    }

    /// <summary>
    /// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    /// <summary>
    /// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
    /// </summary>
    /// <param name="disposing">A boolean value indicating whether or not to dispose managed resources</param>
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_context != null)
            {
                _context.Dispose();
                _context = null;
            }
        }
    }
}

As you can see, the repository use a generic type of TEntity to represent an entity that we want to manipulate. Suppose we have an entity named Customer, when we need to perform operations on Customer entity we will do something like this:

IRepository<Customer> customerRepository = new GenericRepository<Customer>();

// Gets all customers
IEnumerable<Customer> customers = customerRepository.GetAll();

// Insert a new customer
Customer customer = new Customer { Firstname = "Huy", Lastname = "Nguyen" };
customerRepository.Add(customer);
customerRepository.SaveChanges();

For some specific entity selection, instead of widening the contract of generic repository, the common technique is to subclass the generic repository to implement a specific repository:

public class CustomerRepository : GenericRepository<Customer>, ICustomerRepository
{
    public CustomerRepository(ObjectContext context) : base(context) { }

    public IList<Customer> NewlySubscribed()
    {
        var lastMonth = DateTime.Now.Date.AddMonths(-1);

        return GetQuery().Where(c => c.Inserted >= lastMonth)
        .ToList();
    }

    public Customer FindByName(string firstname, string lastname)
    {
        return GetQuery().Where(c => c.Firstname == firstname && c.Lastname == lastname).FirstOrDefault();
    }
}

But I find it a bit inconvenient since we have to create multiple repository instances in case we want to work with multiple entities at a time. In other words, if we want to perform operations on n entities, we have to create nearly n repository instances (I am saying ‘nearly’ because if an entity is not an aggregate root, we do not implement a repository for it), like the code below:

private void AddOrders()
{
    var context = new NorthwindEntities("connectionString");

    var customerRepository = new CustomerRepository(context);
    IRepository<Order> orderRepository = new GenericRepository<Order>(context);
    IRepository<Product> productRepository = new GenericRepository<Product>(context);

    var c = customerRepository.FindByName("John", "Doe");

    var winXP = productRepository.Single(x => x.Name == "Windows XP Professional");
    var winSeven = productRepository.Single(x => x.Name == "Windows Seven Professional");

    var o = new Order
    {
        OrderDate = DateTime.Now,
        Purchaser = c,
        OrderLines = new List<OrderLine>
        {
            new OrderLine { Price = 200, Product = winXP, Quantity = 1},
            new OrderLine { Price = 699.99, Product = winSeven, Quantity = 5 }
        }
    };

    orderRepository.Add(o);
    orderRepository.SaveChanges();
}

To get rid of that inconvenient, I decide to re-implement the more generic repository by making the repository’s methods generic:

public interface IRepository : IDisposable
{
    IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class;
    IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class;
    IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
    TEntity Single<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
    TEntity First<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;
    void Add<TEntity>(TEntity entity) where TEntity : class;
    void Delete<TEntity>(TEntity entity) where TEntity : class;
    void Attach<TEntity>(TEntity entity) where TEntity : class;
    void SaveChanges();
    void SaveChanges(SaveOptions options);
}
And here is the implementation for the revised repository contract:
/// <summary>
/// A generic repository for working with data in the database
/// </summary>
/// <typeparam name="T">A POCO that represents an Entity Framework entity</typeparam>
public class GenericRepository : IRepository
{
    /// <summary>
    /// The context object for the database
    /// </summary>
    private ObjectContext _context;
    private readonly PluralizationService _pluralizer;

    /// <summary>
    /// Initializes a new instance of the GenericRepository class
    /// </summary>
    /// <param name="context">The Entity Framework ObjectContext</param>
    public GenericRepository(ObjectContext context)
    {
        _context = context;
        _pluralizer = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en"));
    }

    public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
    {
        var entityName = GetEntityName<TEntity>();
        return _context.CreateQuery<TEntity>(entityName);
    }

    public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class
    {
        return GetQuery<TEntity>().AsEnumerable();
    }

    public IEnumerable<TEntity> Find<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
    {
        return GetQuery<TEntity>().Where(predicate).AsEnumerable();
    }

    public TEntity Single<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
    {
        return GetQuery>TEntity>().Single<TEntity>(predicate);
    }

    public TEntity First<TEntity>(Expression<Func<TEntity, bool>> predicate) where TEntity : class
    {
        return GetQuery<TEntity>().Where(predicate).FirstOrDefault();
    }

    public void Add<TEntity>(TEntity entity) where TEntity : class
    {
        _context.AddObject(GetEntityName<TEntity>(), entity);
    }

    public void Delete<TEntity>(TEntity entity) where TEntity : class
    {
        _context.DeleteObject(entity);
    }

    private string GetEntityName<TEntity>() where TEntity : class
    {
        return string.Format("ObjectContext.{0}", _pluralizer.Pluralize(typeof(TEntity).Name));
    }
    // ...
}
With this repository we can now create only one repository every time we need to retrieve or persist an entity, we can even make this repository an instance member to be retrieved across class methods. Here is the new AddOrders method using this new repository:
private void AddOrders()
{
    var context = new NorthwindEntities("connectionString");

    var customerRepository = new CustomerRepository(context);
    var repository = new GenericRepository(context);

    var c = customerRepository.FindByName("John", "Doe");

    var winXP = repository.Single<Product>(x => x.Name == "Windows XP Professional");
    var winSeven = repository.Single<Product>(x => x.Name == "Windows Seven Professional");

    var o = new Order
    {
        OrderDate = DateTime.Now,
        Purchaser = c,
        OrderLines = new List<OrderLine>
        {
            new OrderLine { Price = 200, Product = winXP, Quantity = 1},
            new OrderLine { Price = 699.99, Product = winSeven, Quantity = 5 }
        }
    };

    repository.Add<Order>(o);
    repository.SaveChanges();
}
Of course one also creates the specific repository to widen the contract using inheritence (like CustomerRepository above) or narrow it using adapter if she wants to.
Unit of Work
The EF ObjectContext does this work for us in regarding managing UnitOfWork. It is already able to handle transaction across many operations over many different types. All we have to do is to call SaveChanges method on the ObjectContext instance as described in the above test code.
With the current implementation so far, we now have a handy generic repository to be used for data persistence and transaction handling. But there is a slight issue with this implementation. The problem being, if I had multiple POCO objects, for instance, Repository<Customer> and Repository<Product>, we would not able to run queries across both, as they would be created via different instances of ObjectContext and this leads to losing any level 1 caching.
A common solution is to build a object context factory. Every time we need an object context instance, just delegate this work to this factory class. Here is a possible implementation:
public static class ObjectContextFactory
{
    /// <summary>
    /// Gets the default ObjectContext for the project
    /// </summary>
    /// <returns>The default ObjectContext for the project</returns>
    public static NorthwindEntities GetContext()
    {
        string connectionString = ConfigurationManager.ConnectionStrings["YourConnection"].ConnectionString;

        return GetContext(connectionString);
    }

    /// <summary>
    /// Gets the default ObjectContext for the project
    /// </summary>
    /// <param name="connectionString">Connection string to use for database queries</param>
    /// <returns>The default ObjectContext for the project</returns>
    public static NorthwindEntities GetContext(string connectionString)
    {
        return new NorthwindEntities(connectionString);
    }
}
To use it, just simply do something like the following:
private void AddOrders()
{
    var context = ObjectContextFactory.GetContext("connectionString");

    var customerRepository = new CustomerRepository(context);
    var repository = new GenericRepository(context);

    var c = customerRepository.FindByName("John", "Doe");

    var winXP = repository.Single<Product>(x => x.Name == "Windows XP Professional");
    var winSeven = repository.Single<Product>(x => x.Name == "Windows Seven Professional");

    var o = new Order
    {
        OrderDate = DateTime.Now,
        Purchaser = c,
        OrderLines = new List<OrderLine>
        {
            new OrderLine { Price = 200, Product = winXP, Quantity = 1},
            new OrderLine { Price = 699.99, Product = winSeven, Quantity = 5 }
        }
    };

    repository.Add<Order>(o);
    repository.SaveChanges();
}
At this time, I again find another inconvenient way to manage the object context. Look at the code above you will easily find that every time we work with another type of object context in another application, we have to rewrite the factory in order for it to return the actual type we need instead of the example NorthwindEntities. Is there a way to make this factory class unchanged so that we can reuse it in every application that works with any concrete instance of object context?
This reminds me about the NHibernate session manager implemented in SharpArchitecture code base. So I decide to write an object context manager which acts like that session manager. Its responsibility is to provide a mechanism to create context on demand, and it also provides a storage mechanism which is context-dependent (http context, wcf, and so on) to store object context.
public static class ObjectContextManager
{
    public static void Init(string[] mappingAssemblies, bool recreateDatabaseIfExist = false)
    {
        Init(DefaultConnectionStringName, mappingAssemblies, recreateDatabaseIfExist);
    }

    public static void Init(string connectionStringName, string[] mappingAssemblies, bool recreateDatabaseIfExist = false)
    {
        AddConfiguration(connectionStringName, mappingAssemblies, recreateDatabaseIfExist);
    }

    public static void InitStorage(IObjectContextStorage storage)
    {
        if (storage == null)
        {
            throw new ArgumentNullException("storage");
        }
        if ((Storage != null) && (Storage != storage))
        {
            throw new ApplicationException("A storage mechanism has already been configured for this application");
        }
        Storage = storage;
    }

    /// <summary>
    /// The default connection string name used if only one database is being communicated with.
    /// </summary>
    public static readonly string DefaultConnectionStringName = "DefaultDb";

    /// <summary>
    /// Used to get the current object context session if you're communicating with a single database.
    /// When communicating with multiple databases, invoke <see cref="CurrentFor()" /> instead.
    /// </summary>
    public static ObjectContext Current
    {
        get
        {
            return CurrentFor(DefaultConnectionStringName);
        }
    }

    /// <summary>
    /// Used to get the current ObjectContext associated with a key; i.e., the key
    /// associated with an object context for a specific database.
    ///
    /// If you're only communicating with one database, you should call <see cref="Current" /> instead,
    /// although you're certainly welcome to call this if you have the key available.
    /// </summary>
    public static ObjectContext CurrentFor(string key)
    {
        if (string.IsNullOrEmpty(key))
        {
            throw new ArgumentNullException("key");
        }

        if (Storage == null)
        {
            throw new ApplicationException("An IObjectContextStorage has not been initialized");
        }

        if (!objectContextBuilders.ContainsKey(key))
        {
            throw new ApplicationException("An ObjectContextBuilder does not exist with a key of " + key);
        }

        ObjectContext context = Storage.GetObjectContextForKey(key);

        if (context == null)
        {
            context = objectContextBuilders[key].BuildObjectContext();
            Storage.SetObjectContextForKey(key, context);
        }

        return context;
    }

    /// <summary>
    /// This method is used by application-specific object context storage implementations
    /// and unit tests. Its job is to walk thru existing cached object context(s) and Close() each one.
    /// </summary>
    public static void CloseAllObjectContexts()
    {
        foreach (ObjectContext ctx in Storage.GetAllObjectContexts())
        {
            if (ctx.Connection.State == System.Data.ConnectionState.Open)
                ctx.Connection.Close();
        }
    }

    private static void AddConfiguration(string connectionStringName, string[] mappingAssemblies, bool recreateDatabaseIfExists = false)
    {
        if (string.IsNullOrEmpty(connectionStringName))
        {
            throw new ArgumentNullException("connectionStringName");
        }

        if (mappingAssemblies == null)
        {
            throw new ArgumentNullException("mappingAssemblies");
        }

        objectContextBuilders.Add(connectionStringName,
            new ObjectContextBuilder<ObjectContext>(connectionStringName, mappingAssemblies, recreateDatabaseIfExists));
    }

    /// <summary>
    /// An application-specific implementation of IObjectContextStorage must be setup either thru
    /// <see cref="InitStorage" /> or one of the <see cref="Init" /> overloads.
    /// </summary>
    private static IObjectContextStorage Storage { get; set; }

    /// <summary>
    /// Maintains a dictionary of object context builders, one per database.  The key is a
    /// connection string name used to look up the associated database, and used to decorate respective
    /// repositories. If only one database is being used, this dictionary contains a single
    /// factory with a key of <see cref="DefaultConnectionStringName" />.
    /// </summary>
    private static Dictionary<string, IObjectContextBuilder<ObjectContext>> objectContextBuilders =
        new Dictionary<string, IObjectContextBuilder<ObjectContext>>();
}
As you can see, ObjectContextManager delegates the job to create an object context to a so-called ObjectContextBuilder class. The main responsibility of this class  is to create an object context using the provided connection string and also to look up and configure the entity mapping classes. This class constructor accepts a connection string name and an array of mapping assemblies, which contain entity definitions and mapping classes, for it to create an object context (these two parameters was provided during application starting up by calling method ObjectContextManager.Init(…)). If you have ever used SharpArchitecture code, you can see it is almost the same as NHibernate’s SessionFactory class.
Here is the code of ObjectContextBuilder class:
public interface IObjectContextBuilder<T> where T : ObjectContext
{
    T BuildObjectContext(bool lazyLoadingEnabled = true);
}

public class ObjectContextBuilder<T> : ContextBuilder<T>, IObjectContextBuilder<T> where T : ObjectContext
{
    private readonly DbProviderFactory _factory;
    private readonly ConnectionStringSettings _cnStringSettings;
    private readonly PluralizationService _pluralizer;
    private readonly bool _recreateDatabaseIfExists;

    public ObjectContextBuilder(string connectionStringName, string[] mappingAssemblies, bool recreateDatabaseIfExists)
    {
        _cnStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];
        _factory = DbProviderFactories.GetFactory(_cnStringSettings.ProviderName);
        _pluralizer = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en"));
        _recreateDatabaseIfExists = recreateDatabaseIfExists;

        AddConfigurations(mappingAssemblies);
    }

    /// <summary>
    /// Creates a new <see cref="ObjectContext"/>.
    /// </summary>
    /// <param name="lazyLoadingEnabled">if set to <c>true</c> [lazy loading enabled].</param>
    /// <param name="recreateDatabaseIfExist">if set to <c>true</c> [recreate database if exist].</param>
    /// <returns></returns>
    public T BuildObjectContext(bool lazyLoadingEnabled = true)
    {
        var cn = _factory.CreateConnection();
        cn.ConnectionString = _cnStringSettings.ConnectionString;

        var ctx = Create(cn);
        ctx.ContextOptions.LazyLoadingEnabled = lazyLoadingEnabled;

        if (!ctx.DatabaseExists())
        {
            ctx.CreateDatabase();
        }
        else if (_recreateDatabaseIfExists)
        {
            ctx.DeleteDatabase();
            ctx.CreateDatabase();
        }

        return ctx;
    }

    /// <summary>
    /// Adds mapping classes contained in provided assemblies and register entities as well
    /// </summary>
    /// <param name="mappingAssemblies"></param>
    private void AddConfigurations(string[] mappingAssemblies)
    {
        if (mappingAssemblies == null || mappingAssemblies.Length == 0)
        {
            throw new ArgumentNullException("mappingAssemblies", "You must specify at least one mapping assembly");
        }

        foreach (string mappingAssembly in mappingAssemblies)
        {
            Assembly asm = Assembly.LoadFrom(MakeLoadReadyAssemblyName(mappingAssembly));

            foreach (Type type in asm.GetTypes())
            {
                if (!type.IsAbstract)
                {
                    if (type.IsSubclassOf(typeof(StructuralTypeConfiguration)))
                    {
                        StructuralTypeConfiguration instance = Activator.CreateInstance(type) as StructuralTypeConfiguration;
                        this.Configurations.Add(instance);

                        Type entityType = GetEntityType(type);
                        if (entityType != null)
                        {
                            RegisterEntity(entityType);
                        }
                    }
                }
            }
        }

        if (this.Configurations.Count == 0)
        {
            throw new ArgumentException("No mapping class found!");
        }
    }
    // other code
}
Updated: ADO.NET team just announced the release of Entity Framework Feature  Community Technology Preview 4 (CTP4) which splits ContextBuilder into two components, ModelBuilder and DbModel. The definition of the two new classes are as “ModelBuilder is mutable and exposes the fluent API for defining your model. ModelBuilder creates an immutable DbModel type that can be used to construct an ObjectContext or DbContext. DbModel can also be constructed from a Database First or Model First approach where an edmx file is generated.” Here is the updated ObjectContextBuilder class which replaces the inheritance from ContextBuilder to ModelBuilder class. Note that to make the code compilable, you must install the EF CTP4 version
public interface IObjectContextBuilder<T> where T : ObjectContext
{
    T BuildObjectContext(bool lazyLoadingEnabled = true);
}

public class ObjectContextBuilder<T> : ModelBuilder, IObjectContextBuilder<T> where T : ObjectContext
{
    private readonly DbProviderFactory _factory;
    private readonly ConnectionStringSettings _cnStringSettings;
    private readonly PluralizationService _pluralizer;
    private readonly bool _recreateDatabaseIfExists;

    public ObjectContextBuilder(string connectionStringName, string[] mappingAssemblies, bool recreateDatabaseIfExists)
    {
        _cnStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];
        _factory = DbProviderFactories.GetFactory(_cnStringSettings.ProviderName);
        _pluralizer = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en"));
        _recreateDatabaseIfExists = recreateDatabaseIfExists;

        // we do not want the EdmMedadata table to be generated
        IncludeMetadataInDatabase = false;

        AddConfigurations(mappingAssemblies);
    }

    /// <summary>
    /// Creates a new <see cref="ObjectContext"/>.
    /// </summary>
    /// <param name="lazyLoadingEnabled">if set to <c>true</c> [lazy loading enabled].</param>
    /// <param name="recreateDatabaseIfExist">if set to <c>true</c> [recreate database if exist].</param>
    /// <returns></returns>
    public T BuildObjectContext(bool lazyLoadingEnabled = true)
    {
        var cn = _factory.CreateConnection();
        cn.ConnectionString = _cnStringSettings.ConnectionString;

        // calls ModelBuilder.CreateModel() to create DbModel, then uses it to create ObjectContext
        var ctx = CreateModel().CreateObjectContext<T>(cn);
        ctx.ContextOptions.LazyLoadingEnabled = lazyLoadingEnabled;

        if (!ctx.DatabaseExists())
        {
            ctx.CreateDatabase();
        }
        else if (_recreateDatabaseIfExists)
        {
            ctx.DeleteDatabase();
            ctx.CreateDatabase();
        }

        return ctx;
    }
    // other code are kept the same
}
With this ObjectContextManager in hand, I re-factor the Repository class by removing the dependency to ObjectContext in its constructor, every time it needs a ObjectContext, it will ask the ObjectContextManager to provide.
/// <summary>
/// Generic repository
/// </summary>
public class GenericRepository : IRepository
{
    private readonly ObjectContext _context;
    private readonly PluralizationService _pluralizer;

    /// <summary>
    /// Initializes a new instance of the <see cref="Repository&lt;TEntity&gt;"/> class.
    /// </summary>
    public GenericRepository()
        : this(string.Empty)
    {
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="Repository&lt;TEntity&gt;"/> class.
    /// </summary>
    /// <param name="connectionStringName">Name of the connection string.</param>
    public GenericRepository(string connectionStringName)
    {
        _context = GetObjectContext(connectionStringName);
        _pluralizer = PluralizationService.CreateService(CultureInfo.GetCultureInfo("en"));
    }

    private ObjectContext GetObjectContext(string connectionStringName)
    {
        if (connectionStringName == string.Empty)
            return ObjectContextManager.Current;
        return ObjectContextManager.CurrentFor(connectionStringName);
    }
    // other code
}

So far so good, here is the revisited test code:

[TestFixture]
public class RepositoryTest
{
    private ICustomerRepository customerRepository;
    private IRepository orderRepository;
    private IRepository productRepository;

    [TestFixtureSetUp]
    public void SetUp()
    {
        ObjectContextManager.InitStorage(new SimpleObjectContextStorage());
        ObjectContextManager.Init("DefaultDb", new[] { "Infrastructure.Tests" }, true);

        customerRepository = new CustomerRepository();
        orderRepository = new GenericRepository();
        productRepository = new GenericRepository();
    }

    private void AddOrders()
    {
        var c = customerRepository.FindByName("John", "Doe");

        var winXP = productRepository.FindOne<Product>(x => x.Name == "Windows XP Professional");
        var winSeven = productRepository.FindOne<Product>(x => x.Name == "Windows Seven Professional");

        var o = new Order
        {
            OrderDate = DateTime.Now,
            Purchaser = c,
            OrderLines = new List<OrderLine>
            {
                new OrderLine { Price = 200, Product = winXP, Quantity = 1},
                new OrderLine { Price = 699.99, Product = winSeven, Quantity = 5 }
            }
        };

        orderRepository.Add(o);
        orderRepository.SaveChanges();
    }
}
The Specification pattern
According to Martin Flowler, the idea of Specification is to separate the statement of how to match a candidate, from the candidate object that it is matched against. As well as its usefulness in selection, it is also valuable for validation and for building to order. You can also follow the Specification white paper by Martin Flowler if you want to indulge yourself deeply into this programming pattern.
In simple terms, it is a small piece of logic which is independent and give an answer to the question “does this match ?”. With Specification, we isolate the logic that do the selection into a reusable business component that can be passed around easily from the entity we are selecting.
Okay, it is enough for introducing specification pattern. Here is the specification contract:
public interface ISpecification<TEntity>
{
    bool IsSatisfiedBy(TEntity entity);
}
And the extended repository contract:
public interface IRepository
{
    // other methods..
    TEntity Single<TEntity>(ISpecification<TEntity> criteria) where TEntity : class

    IEnumerable<TEntity> Find<TEntity>(ISpecification<TEntity> criteria) where TEntity : class
}
Now is the implementation of the extended repository:
public class GenericRepository : IRepository
{
    // other code...
    public TEntity Single<TEntity>(ISpecification<TEntity> criteria) where TEntity : class
    {
        return GetQuery<TEntity>().Single<TEntity>(criteria.IsSatisfiedBy);
    }

    public IEnumerable<TEntity> Find<TEntity>(ISpecification<TEntity> criteria) where TEntity : class
    {
        return GetQuery<TEntity>().Where(criteria.IsSatisfiedBy).AsEnumerable();
    }
    // other code...
}
Some of the sample specification implementation:
public class Specification<TEntity> : ISpecification<TEntity>
{
    public Specification(Expression<Func<TEntity, bool>> predicate)
    {
        _predicate = predicate;
    }

    public bool IsSatisfiedBy(TEntity entity)
    {
        return _predicate.Compile().Invoke(entity);
    }

    private Expression<Func<TEntity, bool>> _predicate;
}

public class ProductByNameSpecification : Specification<Product>
{
    public ProductByNameSpecification(string nameToMatch)
        : base(p => p.Name == nameToMatch)
    {
    }
}

public class ProductOnSaleSpecification : Specification<Product>
{
    public ProductOnSaleSpecification() : base(p => p.Price < 100) { }
}
At this point, I think of a technique to chain the specification called composite specification. Why not apply to make the specification flexible and reusable? Here is the code which is mostly inspired from this post:
public class Specification<TEntity> : ISpecification<TEntity>
{
    public Specification(Expression<Func<TEntity, bool>> predicate)
    {
        _predicate = predicate;
    }

    public AndSpecification<TEntity> And(Specification<TEntity> specification)
    {
        return new AndSpecification<TEntity>(this, specification);
    }

    public OrSpecification<TEntity> Or(Specification<TEntity> specification)
    {
        return new OrSpecification<TEntity>(this, specification);
    }

    public NotSpecification<TEntity> Not(Specification<TEntity> specification)
    {
        return new NotSpecification<TEntity>(this, specification);
    }

    public bool IsSatisfiedBy(TEntity entity)
    {
        return _predicate.Compile().Invoke(entity);
    }

    private Expression<Func<TEntity, bool>> _predicate;
}

/// <summary>
/// http://devlicio.us/blogs/jeff_perrin/archive/2006/12/13/the-specification-pattern.aspx
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public abstract class CompositeSpecification<TEntity> : ISpecification<TEntity>
{
    protected readonly Specification<TEntity> _leftSide;
    protected readonly Specification<TEntity> _rightSide;

    public CompositeSpecification(Specification<TEntity> leftSide, Specification<TEntity> rightSide)
    {
        _leftSide = leftSide;
        _rightSide = rightSide;
    }

    public abstract bool IsSatisfiedBy(TEntity entity);
}

public class AndSpecification<TEntity> : CompositeSpecification<TEntity>
{
    public AndSpecification(Specification<TEntity> leftSide, Specification<TEntity> rightSide)
        : base(leftSide, rightSide)
    {
    }

    public override bool IsSatisfiedBy(TEntity obj)
    {
        return _leftSide.IsSatisfiedBy(obj) && _rightSide.IsSatisfiedBy(obj);
    }
}

public class OrSpecification<TEntity> : CompositeSpecification<TEntity>
{
    public OrSpecification(Specification<TEntity> leftSide, Specification<TEntity> rightSide)
        : base(leftSide, rightSide)
    {
    }

    public override bool IsSatisfiedBy(TEntity entity)
    {
        return _leftSide.IsSatisfiedBy(entity) || _rightSide.IsSatisfiedBy(entity);
    }
}

public class NotSpecification<TEntity> : CompositeSpecification<TEntity>
{
    public NotSpecification(Specification<TEntity> leftSide, Specification<TEntity> rightSide)
        : base(leftSide, rightSide)
    {
    }

    public override bool IsSatisfiedBy(TEntity entity)
    {
        return _leftSide.IsSatisfiedBy(entity) && !_rightSide.IsSatisfiedBy(entity);
    }
}
And here is the code to test the composite specification
[TestFixture]
public class RepositoryTest
{
    private ICustomerRepository customerRepository;
    private IRepository orderRepository;
    private IRepository productRepository;

    [TestFixtureSetUp]
    public void SetUp()
    {
        ObjectContextManager.InitStorage(new SimpleObjectContextStorage());
        ObjectContextManager.Init("DefaultDb", new[] { "Infrastructure.Tests" }, true);
        customerRepository = new CustomerRepository();
        orderRepository = new GenericRepository();
        productRepository = new GenericRepository();
    }

    [Test]
    public void Test()
    {
        // setup data code..

        FindBySpecification();
        FindByCompositeSpecification();
        FindByConcretSpecification();
        FindByConcretCompositeSpecification();
    }
    private void FindBySpecification()
    {
        Specification<Product> specification = new Specification<Product>(p => p.Price < 100);
        IEnumerable<Product> productsOnSale = productRepository.Find<Product>(specification);
        Assert.AreEqual(2, productsOnSale.Count());
    }

    private void FindByCompositeSpecification()
    {
        IEnumerable<Product> products = productRepository.Find<Product>(
        new Specification<Product>(p => p.Price < 100).And(new Specification<Product>(p => p.Name == "Windows XP Professional")));
        Assert.AreEqual(1, products.Count());
    }

    private void FindByConcretSpecification()
    {
        ProductOnSaleSpecification specification = new ProductOnSaleSpecification();
        IEnumerable<Product> productsOnSale = productRepository.Find<Product>(specification);
        Assert.AreEqual(2, productsOnSale.Count());
    }

    private void FindByConcretCompositeSpecification()
    {
        IEnumerable<Product> products = productRepository.Find<Product>(
        new AndSpecification<Product>(
        new ProductOnSaleSpecification(),
        new ProductByNameSpecification("Windows XP Professional")));
        Assert.AreEqual(1, products.Count());
    }
}
Conclusion
That’s it. I hope you find something useful with the of generic repository, the way to manage object context, and the composite specification implementation as well. Comments are welcome!
References

The code for this post can be found here.

[Bookmark] First and Second Level caching in NHibernate

Found a very good post about “NHibernate first and second level cache”. I myself find the helpful explanation about the different between Session.Get(id) and Session.Load(id)  because I must admit that I was not aware of this until I read this post 🙂

Read it through at: http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/11/09/first-and-second-level-caching-in-nhibernate.aspx

NoSQL with MongoDB, NoRM and ASP.NET MVC

Thought I should keep watching this new trend: Document Databases. Just found a good introduction series about MongoDB, NoRM and ASP.NET MVC:

Part 1 – http://weblogs.asp.net/shijuvarghese/archive/2010/04/16/nosql-with-mongodb-norm-and-asp-net-mvc.aspx

Part 2 – http://weblogs.asp.net/shijuvarghese/archive/2010/04/21/nosql-with-mongodb-norm-and-asp-net-mvc-part-2.aspx

Focusing on the controller’s responsibility

This morning I came across an interesting article about Controller responsibility: http://mhinze.com/focusing-on-the-controllers-responsibility/

This is the excerpt:

A heavyweight controller

public RedirectToRouteResult Ship(int orderId)
{
   User user = _userSession.GetCurrentUser();
   Order order = _repository.GetById(orderId);

   if (order.IsAuthorized)
   {
      ShippingStatus status = _shippingService.Ship(order);

      if (!string.IsNullOrEmpty(user.EmailAddress))
      {
         Message message = _messageBuilder
            .BuildShippedMessage(order, user);

         _emailSender.Send(message);
      }

      if (status.Successful)
      {
         return RedirectToAction("Shipped", "Order", new {orderId});
      }
   }
   return RedirectToAction("NotShipped", "Order", new {orderId});
}

According to the author, that controller does a lot of things, so he suggests a refactoring techniques called “Refactor Architecture by Tiers. It directs the software designer to move processing logic out of the presentation tier into the business tier.”

Here is how the controller is refactored by moving the logic for shipping an order to an OrderShippingService, our action is much simpler.

A simpler action after refactoring architecture by tiers
public RedirectToRouteResult Ship(int orderId)
{
   var status = _orderShippingService.Ship(orderId);
   if (status.Successful)
   {
      return RedirectToAction("Shipped", "Order", new {orderId});
   }
   return RedirectToAction("NotShipped", "Order", new {orderId});
}

I must admit that I have implemented that so-called _heavyweight_ controller when developing website using ASP.NET MVC and I rather call it a ‘fat’ controller which violates Single Responsibility Principal since it does a lot of things. My solution is somewhat familiar with the author: moved the logic to Service or Business layer. This will keep the controller ‘thin’ and concentrates on its responsibility: a coordinator between View and Model which intercepts user request, asking  business layer to perform business logic, pull data from Model and choose a right View to return to client.

And it takes time, even blood, to absorb.

Lesson learned from building Bua An VIET Website

There are many things worth noting after finishing the phase 1 of Bua An VIET:

– This is the first time I built a website using ASP.NET MVC (1.0), although I have some experiences with ASP.NET Web Forms, there still are too many things to learn, especially, implement custom model binder to fetch complex object graph, how to do ajax with jQuery, how routing works and how to make it works as expected via routing configuration.

– Working with NHibernate has been more and more of pleasure. Fluent NHibernate is handy and it saves me time to debug mapping error. S#arp Architect is a great open source web framework to be employed. I really like the way that NHibernate Session is managed, although I am not applying Repository pattern like its reference implementation (Northwind sample).

jQuery is awesome.

– It took me a lot of time to deal with CSS because of lacking deep understanding on it or my knowledge is outdated. Knowing many resources of CSS and jQuery helped me out, but it still took me time.

– I must admit that building web development requires good graphic design skill, and I don’t have one. Wandering over internet to choose a right template is a way to do, but it is also time consuming and when I want to change the layout/template with a new one, I nearly have to start over with another messy html and CSS.

– A number of design patterns and design principals have been being applied. This is where I learnt a lot. Some of design pattern which I always think it must be applied and/or some principals I always think it is true have becomes not suitable and/or over complicated, at least to me. I learnt the fact that “Theory  is  just pink, and trees are always green”

– We are planning to add more features to the site, also an upgrade to ASP.NET MVC 2 is planned. This will bring more useful information to the user and more fun to me.

Use MSDeploy to generate import data script

I just found a very helpful tool to generate import data script when deploying database: msdeploy

First download it from here. The tool will be installed in “C:\Program Files\IIS\Microsoft Web Deploy” by default.

To use the tool, fire up command line, go to “C:\Program Files\IIS\Microsoft Web Deploy”  (assume that the tool has been installed in this folder). And type in this command:

C:\Program Files\IIS\Microsoft Web Deploy>msdeploy.exe -verb:sync -source:dbFullSql=”Data Source=[DATABASESERVER]; Initial Catalog=[DATABASENAME];Integrated Security=false ;user id=[USERID];password=[PASSWORD]”,IncludeData=[INCLUDE_DATA],IncludeSchema=[INCLUDE_SCHEMA] -dest:dbFullSql=”[FULL_PATH_TO_SCRIPT_FILE]”

  • [DATABASESERVER]: Computer name or IP address of database server
  • [DATABASENAME]: The name of database from which data are going to be exported
  • [USERID]: Id of user who has access rights to the database server
  • [PASSWORD]: Password to login to database server
  • [INCLUDE_SCHEMA]: Possible values are True or False. If this value is True, the database schema will also be generated
  • [INCLUDE_DATA]: Possible values are True or False. Set this to true to generate import data script
  • [FULL_PATH_TO_SCRIPT_FILE]: the name of the output script file including a path, i.e. C:\DataLoad.sql

Enjoy!