7. 9. 2010

Generic Repository

In this article I'd like to introduce you into the open source project Generic Repository.

The need for Generic Repository
Repository pattern is important part of almost all (web) applications these days. You can see it spreaded out in many applications, tutorials, examples, videos and demos. Everybody is trying to solve one common problem and everybody is doing it differently. Is there a way to unify this?

Generic Repository is open source project that aims to unify implementation of repository pattern and the design of interfaces and queries. Additionaly it provides out of box the implementations for all most popular data mappers like NHibernate, Entity Framework, Linq2Sql or nosql mappers.

Generic repository is not a pattern. It is an unification of implementation of the repository pattern. It provides a base for all repositories you will need in your application. In this way you can easily reuse the code in different application as they will use the same design of the repositories. If other devs are already using generic repository, there is no learning curve as they already know the infrastructure, so it is very easy to adopt it. As a nice side benefit the generic repository provides you the way to change the data mapper. It is not trivial task but with unified interface you can do it without touching your business logic. It is even possible to integrate more than one data mappers and switch between them using one setting in config file.

Example of usage can be found below:
var customer = new Customer { Name = "Peter Bondra", Age = 37 };

var specificationLocator =
  this.IoC.Resolve<ISpecificationLocator>();


using ( var unitOfWork = this.IoC.Resolve<IUnitOfWorkFactory>().BeginUnitOfWork() )
{
  ICustomerRepository cr = this.IoC.Resolve<ICustomerRepository>(unitOfWork, specificationLocator);

  using ( var transaction = unitOfWork.BeginTransaction() )
  {
    cr.Insert(customer);
    transaction.Commit();
  }
}

There are many implementations in repository pattern out there, and most devs are learning it from the demo examples in the internet. One thing that I'd like to point out is the missunderstading of the pattern in respect to queries. I've seen a repository interface with hundrets of various methods to support all kind of queries the application required  - and yes, it was just demo app. Btw the implementation went directly from Microsoft. Most of the devs are adopting this wrong approach into their application, that are often enterprise (or will grow for sure one day to enterprise level).

Generic repository is solving this problem of many query methods in the interface with divide and conquer approach (and with a little help of inversion of control pattern).

ICustomerRepository customerRepository =
  this.IoC.Resolve<ICustomerRepository>(unitOfWork, specificationLocator);

IList<Customer> =
  customerRepository.Specify<ICustomerSpecification>()
  .NameStartsWith("Peter")
  .OlderThan(18)
  .ToResult()
  .Take(3)
  .ToList();

With unified way and out of box tested implementation you can speed up your development and concetrate on the business logic and rules, instead of fighting with repositories and data mappers. Of course you still will have to write your mappings (unless you use schemaless database like nosql Raven). But repository layer has been solved and tested for you and the effort (and the money) can go to other layers.

Check out the sources at http://code.google.com/p/genericrepository/ and let authors know your feedback. There is no one way to do things and if you have ideas for improvements or changes, you can commit a comment on the webside or by mail.

Žiadne komentáre:

Zverejnenie komentára