Translate

Sunday, September 22, 2013

Repository Pattern C# (Simple introduction to repository pattern in C#)

In this article I will present a very simple repository pattern. I am not applying unit of work pattern here to keep the example simple. (In most real world scenarios you would be using unit of work along with Repository pattern).

What is the problem we are trying to solve?

The primary aim of the repository pattern is make your code in the business layer totally independent of the way you access data. It shouldn't matter to the business logic whether the underlying datastore is in SQL server or coming from a webservice. In the business layer I should be purely concerned about implementing the business rules.

In other words, repository pattern is meant for separation of concerns. We want to separate out the business logic and the data access code. This makes the code easier to test and maintain.

How is this done?
We have a class in between the business layer and the database that acts like a collection. The business layer acts on this repository as if its an in memory collection. For example suppose you are writing the business layer and I am writing the repository class. All you would do to add a person to the database is do something like

var priyanka = new Person {Age = 26, Id = 9, Name = "Priyanka"};
var personRepository = new PersonRepository();

personRepository.Add(priyanka);


Notice here that you are acting upon a PersonRepository object. Even if we move from SQL to XML, only the code in the PersonRepository class will change. The code in your business layer remains unchanged.

C# code that implements repository pattern

using System;
using System.Collections.Generic;
using System.Linq;

namespace RepositoryPattern
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var priyanka = new Person {Age = 26, Id = 9, Name = "Priyanka"};
            var tim = new Person {Age = 40, Id = 10, Name = "Tim"};
            
            var personRepository = new PersonRepository( );

            //Add
            personRepository.Add(priyanka);
            personRepository.Add(tim);

            //Update
            Person victor = personRepository.Find(p => p.Id == 5).Single();
            victor.Age = 66;

            //Remove
            personRepository.Remove(tim);

            foreach (Person person in personRepository.Find(p => p.Id > 0))
            {
                Console.WriteLine("Name:{0} ,Age:{1}", person.Name, person.Age);
            }
        }
    }

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }


    internal interface IPersonRepository
    {
        void Add(Person person);
        void Remove(Person person);
        IEnumerable<Person> Find(Func<Person, bool> predicate);
    }

    public class PersonRepository : IPersonRepository
    {
        private readonly List<Person> _people;

        public PersonRepository()
        {
            _people = FakeDatabase.GetAllPeople();
        }

        public void Add(Person person)
        {
            _people.Add(person);
        }

        public void Remove(Person person)
        {
            _people.Remove(person);
        }


        public IEnumerable<Person> Find(Func<Person, bool> predicate)
        {
            return _people.Where(predicate);
        }
    }

    public class FakeDatabase
    {
        public static List<Person> GetAllPeople()
        {
            var people = new List<Person>
                {
                    new Person {Id = 1, Age = 28, Name = "Tom"},
                    new Person {Id = 2, Age = 32, Name = "Jane"},
                    new Person {Id = 3, Age = 26, Name = "Frieda"},
                    new Person {Id = 4, Age = 54, Name = "John"},
                    new Person {Id = 5, Age = 52, Name = "Victor"},
                };

            return people;
        }
    }
}


6 comments:

Comments will appear once they have been approved by the moderator