Сервисный уровень повторяют мои репозитории - PullRequest
2 голосов
/ 21 мая 2010

Я разрабатываю приложение, используя asp.net mvc, NHibernate и DDD. У меня есть сервисный уровень, который используется контроллерами моего приложения. Все используют Unity для внедрения зависимостей (ISessionFactory в репозитории, репозитории в сервисах и сервисы в контроллерах) и отлично работают.

Но, очень часто мне нужен метод в сервисе, чтобы получить только объект в моем репозитории, такой как (в классе сервиса):

public class ProductService {

   private readonly IUnitOfWork _uow;
   private readonly IProductRepository _productRepository;

   public ProductService(IUnitOfWork unitOfWork, IProductRepository productRepository) {
      this._uow = unitOfWork;
      this._productRepository = productRepository;
   }

   /* this method should be exists in DDD ??? It's very common */
   public Domain.Product Get(long key) {
      return _productRepository.Get(key);
   }

   /* other common method... is correct by DDD ? */
   public bool Delete(long key) {
      usign (var tx = _uow.BeginTransaction()) {
         try 
         {
           _productRepository.Delete(key);
           tx.Commit();
           return true;
         } catch {
           tx.RollBack();
           return false;
         }        
      }
   }

   /* ... others methods ... */

}

Этот код верен DDD? Для каждого класса обслуживания у меня есть репозиторий, и для каждого класса обслуживания нужно сделать метод "Get" для сущности?

Спасибо, ребята

Приветствия

Ответы [ 2 ]

9 голосов
/ 24 мая 2010

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

Давайте поговорим об удалении товаров. Это так же просто, как выполнить удаление в базе данных (NHibernate, или как?), Я думаю, что это не так. Как насчет заказов, которые ссылаются на подлежащий удалению продукт? И так далее. Кстати, Уди Дахан написал замечательную статью об удалении сущностей.

Суть в том, что если ваше приложение настолько простое, что сервисы действительно реплицируют ваши репозитории и содержат только операции CRUD, вы, вероятно, не должны выполнять DDD, отбрасывать свои репозитории и позволять сервисам работать с сущностями (которые будут простыми данными). контейнеры в этом случае).

С другой стороны, если есть сложное поведение (например, с обработкой «удаленных» продуктов), есть смысл идти по пути DDD, и я настоятельно рекомендую это делать.

PS. Несмотря на то, какой подход (DDD или нет) вы в конечном итоге выберете, я бы посоветовал вам использовать некоторое Аспектно-ориентированное программирование для обработки транзакций и исключений. В итоге вы получите доступ ко многим методам, таким как DeleteProduct с тем же TX и кодом обработки исключений.

1 голос
/ 21 мая 2010

Это выглядит правильно с моей точки зрения. Мне действительно не нравилось повторять имена сервисов и методов репозитория снова и снова в моем проекте asp.net MVC, поэтому я выбрал общий подход / шаблон репозитория. Это означает, что мне действительно нужен только один или два метода Get () в моем репозитории для извлечения моих объектов. Это возможно для меня, потому что я использую Entity Framework, и у меня просто есть метод get () моего репозитория, возвращающий IQueryable. Тогда я могу просто сделать следующее:

Product product = from p in _productRepository.Get() where p.Id == Id select p; 

Вероятно, вы можете повторить это в NHibernate с помощью linq -> NHibernate.


Редактировать: Это работает для DDD, потому что это все еще позволяет мне обмениваться моими DAL / репозиториями, пока используемая мной библиотека данных (Nhibernate, EF и т.

Я не уверен, как сделать общий репозиторий без IQueryable, но вы можете использовать функции делегатов / лямбда для его включения.


Edit2: И на тот случай, если я не правильно ответил на ваш вопрос, если вы спрашиваете, должны ли вы вызывать метод Get () вашего хранилища из службы, тогда да, это правильный дизайн DDD, так как Что ж. Причина в том, что сервисный уровень должен обрабатывать всю вашу бизнес-логику, поэтому он точно определяет, как и какие данные извлекать (например, хотите ли вы, чтобы они были в алфавитном порядке, неупорядоченные и т. Д.) Это также означает, что он может выполнять проверку после загрузки, если необходимо, или проверку перед удалением и / или сохранением.

Это означает, что сервисный уровень не заботится о том, как именно эти данные хранятся и извлекаются, он только решает, какие данные хранятся и извлекаются. Затем он вызывает хранилище для правильной обработки запроса и извлечения / сохранения данных в соответствии с указаниями уровня обслуживания. Таким образом, у вас есть правильное разделение интересов.

...