Search code examples
asp.net-mvcooprepository-patternservice-layer

Difference between Repository and Service Layer?


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!!


Solution

  • 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...}     
                 }
             );
         }
    }