Разница между репозиторием и уровнем сервиса?



в шаблонах проектирования ООП, в чем разница между шаблоном репозитория и уровнем сервиса?



Я работаю над ASP.NET MVC 3 приложение, и я пытаюсь понять эти шаблоны проектирования, но мой мозг просто не получает его...еще бы!!

630   5  

5 ответов:

слой репозитория дает вам дополнительный уровень абстракции над доступом к данным. Вместо того, чтобы писать

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

чтобы получить один элемент из базы данных, вы используете репозиторий интерфейс

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

и звонок Get(id). Слой репозитория предоставляет basic CRUD операции.

уровень сервиса предоставляет бизнес-логику, которая использует репозиторий. Пример сервиса может выглядеть так:

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

пока List() способ хранилище возвращает всех пользователей, ListUsers() из IUserService может вернуть только те, к которым пользователь имеет доступ.

In ASP.NET MVC + EF + SQL SERVER, у меня есть этот поток связи:

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

уровень сервиса - > уровень репозитория - > EF эта часть работает на моделях.

Views Service layer этот деталь работает на моделях вида.

EDIT:

пример потока для / Orders/ByClient / 5 (мы хотим видеть заказ для конкретного клиента):

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

это интерфейс для обслуживания заказа:

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

этот интерфейс возвращает модель вид:

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

это реализация интерфейса. Он использует классы моделей и репозиторий для создания модели представления:

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

Как сказал карнотавр, репозиторий отвечает за отображение ваших данных из формата хранения в бизнес-объекты. Он должен обрабатывать как чтение, так и запись данных(удаление, обновление тоже) из и в хранилище.

цель сервисного уровня, с другой стороны, заключается в инкапсуляции бизнес-логики в одно место для содействия повторному использованию кода и разделению проблем. Что это обычно означает для меня на практике при строительстве Asp.net сайты MVC-это то, что у меня есть это структура

[контроллер] вызывает [сервис( ы)] кто вызывает [репозиторий(ы)]

один принцип, который я нашел полезным, - это свести логику к минимуму в контроллерах и репозиториях.

в контроллерах это, потому что это помогает держать меня сухая. Очень часто мне нужно использовать ту же фильтрацию или логику где-то еще, и если я поместил ее в контроллер, я не могу ее повторно использовать.

в репозиториях это потому, что я хочу иметь возможность заменить мой хранение (или ORM), когда приходит что-то лучшее. И если у меня есть логика в репозитории, мне нужно переписать эту логику при изменении репозитория. Если мой репозиторий возвращает только IQueryable, а служба выполняет фильтрацию с другой стороны, мне нужно будет только заменить сопоставления.

например, я недавно заменил несколько моих репозиториев Linq-to-Sql на EF4, и те, где я остался верен этому принципу, могли быть заменены в течение нескольких минут. Где у меня была какая-то логика вместо этого это был вопрос нескольких часов.

обычно репозиторий используется в качестве лесов для заполнения ваших объектов - уровень сервиса будет выходить и отправлять запрос. Вполне вероятно, что вы разместите репозиторий под своим уровнем сервиса.

принятый ответ (и поддержанный сотни раз) имеет серьезный недостаток. Я хотел указать на это в комментарии, но он просто будет похоронен там, в 30-то комментарии, чтобы отметить здесь.

Я взял на себя корпоративное приложение, которое было построено таким образом, и моя первоначальная реакция была WTH? ViewModels в сервисном слое? Я не хотел менять конвенцию, потому что в нее вошли годы разработки, поэтому я продолжал возвращать ViewModels. Мальчик это превратилось в кошмар, когда мы начали использовать WPF. Мы (команда разработчиков) всегда говорили: какой ViewModel? Реальный (тот, который мы написали для WPF) или сервисы? Они были написаны для веб-приложения и даже IsReadOnly флаг для отключения редактирования в пользовательском интерфейсе. Главный недостаток и все из-за одного слова: ViewModel!!

прежде чем вы сделаете ту же ошибку, вот еще несколько причин, в дополнение к моей истории выше:

возврат ViewModel из уровня сервиса-это огромное Нет нет. Это все равно что сказать:

  1. Если вы хотите использовать эти услуги, вам лучше использовать MVVM, и вот ViewModel, который вам нужно использовать. Оуч!

  2. сервис делает предположение, что они будут отображаться в пользовательском интерфейсе где-то. Что делать, если он используется не UI приложения, такие как веб-службы или windows услуги?

  3. Это даже не настоящий ViewModel. реальный ViewModel имеет наблюдаемость, команды и т. д. Это просто POCO с плохим именем. (См. мою историю выше, Почему имена имеют значение.)

  4. потребляющее приложение лучше быть слоем представления (ViewModels используются этим слоем), и он лучше понимает C#. Еще Ой!

пожалуйста, не делай этого!

уровень репозитория реализован для доступа к базе данных и помогает расширить операции CRUD в базе данных. В то время как уровень сервиса состоит из бизнес-логики приложения и может использовать уровень репозитория для реализации определенной логики, включающей базу данных. В приложении лучше иметь отдельный уровень репозитория и уровень сервиса. Наличие отдельных уровней репозитория и сервиса делает код более модульным и отделяет базу данных от бизнес-логики.

Comments

    Ничего не найдено.