MVC3 Предоставление функциональности репозитория через сервис - PullRequest
1 голос
/ 04 июня 2011

Я немного поигрался с asp.net MVC3 и изо всех сил пытался решить, где разместить свою бизнес-логику. Сейчас я остановился на использовании сервисного слоя:

    public class AnimalsService : IAnimalsService
    {
        private readonly IAnimalsRepository _animalsRepository;

        public AnimalsService(IAnimalsRepository animalsRepository)
        {
            _animalsRepository = animalsRepository;
        }
        public IQueryable<Animal> GetFiveLeggedAnimals()
        {
        ...
        }
    }

Контроллер будет выглядеть примерно так:

public class AnimalsController : Controller
{        
    private readonly IAnimalsService _animalsService;

    public AnimalsController(IAnimalsService animalsService)
    {
        _animalsService = animalsService;
    }

    public ViewResult ListFiveLeggedAnimals()
    {
        var animals = _animalsService.GetFiveLeggedAnimals();
        return View(animals);
    }
}

У меня есть базовая логика CRUD в хранилище (Все, Найти, UpdateOrInsert, Удалить). Если я хочу использовать эти методы CRUD в моем контроллере:

1) Нужно ли создавать методы-оболочки в службе для этих вызовов репозитория?

2) Разве для меня не имеет смысла просто включать метод GetFiveLeggedAnimals и другую бизнес-логику в репозиторий?

3) Могу ли я реализовать интерфейс IAnimalsRepository в AnimalsService и затем вызывать базовые методы (я понимаю, что это возможно, но я предполагаю, что это плохая практика)?

Ответы [ 3 ]

3 голосов
/ 04 июня 2011

1) Должен ли я создавать методы-оболочки в службе для этих вызовов репозитория?

В основном, да.Как правило, вы хотите предложить CRUD для моделей вашего домена на уровне обслуживания.Таким образом, контроллеру не нужно работать с репозиторием напрямую (фактически, он никогда не должен).Вы можете добавить более сложную логику позже без необходимости изменения внешнего кода.Например, рассмотрим, что вы хотели реализовать ленту новостей.Теперь каждый раз, когда вставляется пятиногое животное, вы хотите создать новость и передать ее любителям пятиногого животного.Другим распространенным примером являются уведомления по электронной почте.

2) Разве для меня не имеет смысла просто включать метод GetFiveLeggedAnimals и другую бизнес-логику в хранилище?

Businessлогика должна быть в Service Layer или в Domain Model самих объектах и ​​только там.На самом деле (см. 3) я бы вообще не предлагал IAnimalRepository, если это возможно.

Например, в среде NoSQL драйвер базы данных в значительной степени является хранилищем.С другой стороны, при использовании сложного отображения ORM и хранимых процедур (где часть логики biz находится в БД), у вас действительно нет выбора, но вы предлагаете явные интерфейсы, которые знают хранимые процедуры.

Я бы пошел на IRepository<T> и использовал бы шаблон Query Object , если это возможно.Я думаю, что LINQ также можно рассматривать как Объект запроса / Шаблон репозитория .

3) Могу ли я реализовать интерфейс IAnimalsRepositoryв AnimalsService и затем вызывать базовые методы (я понимаю, что это возможно, но я предполагаю, что это плохая практика)?

Чтобы вызвать base методы, вам придется наследоватьот конкретной реализации, например, от ConcreteAnimalsRepository.

Кроме того, если ваша служба прямо или косвенно реализует интерфейс IAnimalsRepository, она делает (нефильтрованные) операции CRUD доступными для всех.

Мое заключение: Не наследуйте,совокупный .Сервисный уровень имеет хранилище, но он не является самим хранилищем: сервисный уровень обрабатывает всю дополнительную логику приложения (разрешения, уведомления), а хранилище является очень тонкой оболочкойвокруг слоя db.

В качестве крайнего примера, что, если удаление чего-либо напрямую было запрещено, и только сервису было бы разрешено использовать его при вставке более новой версии sth.?Это легко построить при агрегировании.

1 голос
/ 05 июня 2011

Репозиторий по определению должен быть общим классоподобным классом, который абстрагирует взаимодействия с БД.Он будет содержать типичные методы для сохранения, такие как Get(object id), Add(T), Remove(T) и, возможно, реализовать IQueryable<T>.

Служба будет выглядеть следующим образом.

0 голосов
/ 04 июня 2011

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

, посмотрите на пример

    // not good design
public ActionResult Create(AnimalInput input)
{
     Animal animal = new Animal { Name = input.Name}; // set the other propreties
    // if you have a CRUD operations in service class you will call
    animalService.UpdateOrInsert(animal);

}
// better disign
public ActionResult Create(AnimalInput input)
{

    animalService.Create(input.Name);

}

в реализации класса обслуживания, вы должны следовать

public void Create(string name)
  {
    Animal animal = new Animal { Name = input.Name};
   animalRepository.UpdateOrInsert(animal);
  }

для таких методов, как GetAll или GetFiveLeggedAnimals ();Вы можете иметь обертку в классах обслуживания, я думаю, что это нормально.И я хочу, чтобы вы всегда получали рекламу, когда вы пишете некоторый код в контроллере или в классе Service, помните, как вы будете тестировать этот код, и не забывайте о SOLID

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...