Как реализовать сторону запроса CQRS в DDD? - PullRequest
16 голосов
/ 04 октября 2009

Я реализовал командную сторону DDD, используя модель домена и репозитории, но как мне реализовать сторону запросов?

Создаю ли я совершенно новую модель домена для пользовательского интерфейса и где она хранится в структуре проекта ... на уровне домена, уровне пользовательского интерфейса и т. Д.?

Кроме того, что я использую в качестве механизма запросов, я создаю новые репозитории специально для объектов домена UI, что-то кроме репозиториев или что-то еще?

Ответы [ 2 ]

6 голосов
/ 11 октября 2009

Исходя из моего понимания CQRS, вы могли бы создать набор DTO, которые отвечают требованиям экранов пользовательского интерфейса или приложений, которые могут потребоваться для их использования.

То, где это существует в проекте, основано на требованиях, поскольку это будет зависеть от того, собираетесь ли вы показывать эти DTO через веб-сервисы. В этом случае я бы поместил его не на веб-уровне, а на прикладном уровне или выделенном фасадном уровне.

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

Если вы используете ORM и хотите сопоставить свои доменные сущности с DTO, то у вас может быть общий QueryRepository, у которого есть методы, которые принимают спецификацию IS или аналогичную конструкцию для определения ваших запросов, тогда объект DtoAssembler для создания Dtos из вашего домена объектов. Затем у реализации есть объект первого класса для каждого из запросов, которые вы собираетесь выполнить.

Вот довольно надуманный пример, но я надеюсь, что он даст вам идею.

       public interface ISpecification<T>
        {
            Expression<Func<T, bool>> Predicate { get; }

        }

       public class ActiveCustomersSpecification : ISpecification<Customer>
        {
            private Expression<Func<Customer, bool>> predicate;
            public ActiveCustomersSpecification()
            {
                predicate = c => c.IsActive; 
            }
            #region ISpecicfication<Customer> Members

            public Expression<Func<Customer, bool>> Predicate
            {
                get { return predicate; }
            }

            #endregion
        }

        public interface IQueryRepository<T>
        {
            IQueryable<T> GetQuery(ISpecification<T> specification);

            IEnumerable<T> FindAllBy(ISpecification<T> specification); 
        }



public class CustomerDtoAssembler
    {
        public CustomerDto AssembleFrom(Customer customer)
        {
            var customerDto = new CustomerDto
            {
                Id = customer.Id
            };

            return customerDto; 
        }
    }
3 голосов
/ 14 октября 2009

Я думаю, willbt дал вам действительно хорошую начальную точку .

Я бы добавил, что если вы решите и дальше использовать ORM в качестве стратегии доступа к данным для запросов, вам будет разумно рассмотреть вопрос об определении стратегии выборки, адаптированной к данным, к которым вы ожидаете получить доступ ( Кстати, я думаю о NHibernate здесь). Это означает, что вы можете решить, загружать или загружать объекты и коллекции, связанные с конкретным Aggregate Root объектом.

Проект NCommon Ритеша Рао предлагает отличную (незавершенную) демонстрацию того, как определить другую стратегию извлечения для различных целей.

Ритеш действительно объясняет это хорошо в своем блоге.

Идите и посмотрите на источник:

В тесте 'Repository_For_Uses_Registered_Fetching_Strategies' вызов

NHRepository<Order>().For<NHRepositoryTests>()

... вызывает использование стратегий извлечения, зарегистрированных для класса NHRepositoryTests, и, следовательно, OrderItems и продукты будут загружаться без лишних проблем с конфигурациями сопоставления NHibernate.

...