Repository Pattern

If you have ever heard of software design patterns, you have heard of the Gang of Four and their book. It’s the bible on this matter and it would be a disservice not to reference it, but the pattern we will talk about is missing from this book. You instead can find more information here.

In short the repository is an object that sits between your application data and your business logic. It helps (among other things) remove duplicated code, improve testability and provide a strong typed business entity that helps catch errors at compile time.

Repository are used to isolate from data source like databases, file system or a Sharepoint list, and from other difficult to integrate objects like web services. When all your business logic deals with data retrieval or persistence through a repository, you can test your business logic in isolation replacing the real repository with a test double.

To have a better understanding of what’s going on let’s have a look at some code

    class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
        public string Address { get; set; }
    }

    interface IPersonRepository
    {
        Person Get(int id);
        void Create(Person person);
        void Update(Person person);
        void Delete(int id);
    }

    class PersonRepository : IPersonRepository
    {
        private readonly SPList list;
        private readonly PersonSPListItemMapper mapper;

        public PersonRepository(SPWeb web)
        {
            list = web.Lists["Person"];
            mapper = new PersonSPListItemMapper();
        }

        public Person Get(int id)
        {
            SPListItem item = list.GetItemById(id);
            Person person = mapper.From(item);
            return person;
        }

        public void Create(Person person)
        {
            SPListItem item = list.AddItem();
            mapper.Populate(item, person);
            item.Update();
        }

        public void Update(Person person)
        {
            SPListItem item = list.GetItemById(person.Id);
            mapper.Populate(item, person);
            item.Update();
        }

        public void Delete(int id)
        {
            SPListItem item = list.GetItemById(id);
            item.Delete();
        }
    }

    class PersonSPListItemMapper
    {
        public Person From(SPListItem item)
        {
            return new Person
            {
                Name = item.Title,
                Id = item.ID,
                BirthDate = (DateTime)item["DateOfBirth"],
                Address = (string)item["Address"]
            };
        }

        public void Populate(SPListItem item, Person person)
        {
            item["Title"] = person.Name;
            item["DateOfBirth"] = person.BirthDate;
            item["Address"] = person.Address;
        }
    }

Here we see, in oder, the business entity we are interested on (Person), with a few basic properties, then the interface of our repository with a few basic CRUD operations, then we implement said interface against a sharepoint list, at the end we have a utility class that’s meant only to map to and from a sharepoint item.

The repository pattern is quite simple to comprehend, what’s important is that:

  • You keep following it
  • Every object in the business layer interacts with the entities through a repository
  • Every interaction is isolated by an interface

The following is a business layer object that expects a repository in its contructor and uses it to create a Person.

    internal class PersonManager
	{
		IPersonRepository repository;
		public PersonManager(IPersonRepository repository)
		{
			this.repository = repository;
		}
		public void Create(string name, string address, DateTime birthDate)
		{
			Person person = new Person
			{
				Name = name,
				BirthDate = birthDate,
				Address = address
			}
			repository.Create(person);
		}
	}

As you can see this class has no knowledge of what is Sharepoint and can be tested quite easily by passing a spy to the constructor instead of the real implementation.

All operations to persist a business entity pass through a repository, and any data retrieved by a query comes from it. In my example you can see a simple get by id query, but more complex queries are allowed. You can implement them in two ways:

  • The repository has a method for each query
  • The repository receives a query object that contains the required information to build a query

Another important advantage of using the repository pattern is that it can provide a centralized caching layer to for the rest of the application. This way if a query has already been served the repository can return a cached result set without having to muck the details of the business layer. This is quite useful when dealing with repositories that mask web services.

In the end, repository help isolate data access code, from the rest of your application, it provides an insertion point to test your business layer but adds another abstraction layer so it can be difficult to understand for developers in your team whom are unfamiliar with this pattern. Also keep in mind that repositories tend to be hard to unit test, so it is better to write integration test for them.

Advertisements

2 thoughts on “Repository Pattern

  1. Pingback: Testing your sharepoint repositories – Code cleaners

  2. Pingback: Testing your sharepoint repositories – Code Cleaners Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s