Difference between Repository and Service Layer?

Sam picture Sam · Feb 19, 2011 · Viewed 87.8k times · Source

In OOP Design Patterns, what is the difference between the Repository Pattern and a Service Layer?

I am working on an ASP.NET MVC 3 app, and am trying to understand these design patterns, but my brain is just not getting it...yet!!

Answer

LukLed picture LukLed · Feb 19, 2011

Repository Layer gives you additional level of abstraction over data access. Instead of writing

var context = new DatabaseContext();
return CreateObjectQuery<Type>().Where(t => t.ID == param).First();

to get a single item from database, you use repository interface

public interface IRepository<T>
{
    IQueryable<T> List();
    bool Create(T item);
    bool Delete(int id);
    T Get(int id);
    bool SaveChanges();
}

and call Get(id). Repository layer exposes basic CRUD operations.

Service layer exposes business logic, which uses repository. Example service could look like:

public interface IUserService
{
    User GetByUserName(string userName);
    string GetUserNameByEmail(string email);
    bool EditBasicUserData(User user);
    User GetUserByID(int id);
    bool DeleteUser(int id);
    IQueryable<User> ListUsers();
    bool ChangePassword(string userName, string newPassword);
    bool SendPasswordReminder(string userName);
    bool RegisterNewUser(RegisterNewUserModel model);
}

While List() method of repository returns all users, ListUsers() of IUserService could return only ones, user has access to.

In ASP.NET MVC + EF + SQL SERVER, I have this flow of communication:

Views <- Controllers -> Service layer -> Repository layer -> EF -> SQL Server

Service layer -> Repository layer -> EF This part operates on models.

Views <- Controllers -> Service layer This part operates on view models.

EDIT:

Example of flow for /Orders/ByClient/5 (we want to see order for specific client):

public class OrderController
{
    private IOrderService _orderService;

    public OrderController(IOrderService orderService)
    {
        _orderService = orderService; // injected by IOC container
    }

    public ActionResult ByClient(int id)
    {
        var model = _orderService.GetByClient(id);
        return View(model); 
    }
}

This is interface for order service:

public interface IOrderService
{
    OrdersByClientViewModel GetByClient(int id);
}

This interface returns view model:

public class OrdersByClientViewModel
{
     CientViewModel Client { get; set; } //instead of ClientView, in simple project EF Client class could be used
     IEnumerable<OrderViewModel> Orders { get; set; }
}

This is interface implementation. It uses model classes and repository to create view model:

public class OrderService : IOrderService
{
     IRepository<Client> _clientRepository;
     public OrderService(IRepository<Client> clientRepository)
     {
         _clientRepository = clientRepository; //injected
     }

     public OrdersByClientViewModel GetByClient(int id)
     {
         return _clientRepository.Get(id).Select(c => 
             new OrdersByClientViewModel 
             {
                 Cient = new ClientViewModel { ...init with values from c...}
                 Orders = c.Orders.Select(o => new OrderViewModel { ...init with values from o...}     
             }
         );
     }
}