фонГде определить интерфейсы для репозитория в многоуровневой архитектуре?
Я пытаюсь создать простое приложение, чтобы действительно понять весь стек DDD + TDD + и др. Моя цель - динамически вводить классы репозитория DAL во время выполнения. Это позволяет тестировать уровни доменов и приложений приложений . Я планирую использовать «бедняк DI» для достижения это сейчас ... так что я хотел бы сделать это в простом приложении консоли рядом с запуском:
// Poor man's DI, injecting DAL repository classes at runtime var productRepository = new SimpleOrder.Repository.ProductRespository(); var customerRepository = new SimpleOrder.Repository.CustomerRepository(); var orderRepository = new SimpleOrder.Repository.OrderRepository(); // Constructor injection into this class in the Application Services layer, // SimpleOrder.ApplicationFacade OrderEntry oe = new OrderEntry(customerRepository, orderRepository, productRepository);
Для достижения этой инъекции зависимостей, я создал три хранилищу интерфейсы:
-- ICustomerRepository -- IOrderRepository -- IProductRespository
типичная реализация:
namespace SimpleOrder.Domain.Interfaces { public interface ICustomerRepository { Customer GetCustomerById(int customerId); void SaveCustomer(Customer customer); } }
** Обратите внимание, что SaveCustomer ссылается на класс модели клиента, определенный в Doma в слое. Это типично для других репозиториев.
ОДНАКО Я не уверен, какой проект/слой, они должны быть реализованы в I 5 проектов в растворе:
SimpleOrder.ConsoleClient (презентация) - Я хочу, чтобы впрыснуть. конкретная реализация домена здесь в качестве приложения
SimpleOrder.ApplicationFacade (услуги приложений) - коренастого более высокого уровня, более крупных зерен способов оплаты rchestrating методы нижнего уровня в домене
SimpleOrder.Contracts - классы DTO, используемые для связи между презентацией и прикладными услугами
SimpleOrder.Domain (домен/BLL) - домен классы моделей клиентов, заказ, OrderItem, продукт
SimpleOrder.Repository (даль) - реализует репо sitory интерфейсы
Вот мои варианты, как я вижу это:
Вариант 1: Определить интерфейсы хранилища в SimpleOrder.Contracts ...
PRO: это где я думаю они должны принадлежать, потому что я создал это для обмена контрактами между различными проблемами/слоями. например, DTO.
CON: однако метод подписи в каждом интерфейсе ссылается на классы модели домена.
Это означает, что мне нужно будет добавить ссылку на SimpleOrder.Domain, но когда SimpleOrder.Контракты ссылаются в другом проекте, он должен будет нести SimpleOrder.Domain для поездки. Это не так.
Вариант 2: тот же сценарий, что и выше, но я также определить интерфейсы для каждого домена модель класса в SimpleOrder.Contracts, так что я могу разорвать связь интерфейсов хранилища для реальных классов модели.
Пример:
namespace SimpleOrder.Domain.Interfaces { public interface ICustomerRepository { ICustomer** GetCustomerById(int customerId); void SaveCustomer(ICustomer customer); } public interface ICustomer { int CustomerId { get; set; } string Name { get; set; } System.Collections.Generic.List Orders { get; } } }
IMPACT: Каждая модель доменный класс должен реализовать свой соответствующий интерфейс. то есть
public class Customer : SimpleOrder.Domain.Interfaces.ICustomer { public Customer() { _orders = new List(); } public int CustomerId { get; set; } public string Name { get; set; } private List _orders; public virtual List Orders { get { return _orders; } } }
PRO: Устраняет проблему Вариант 1.
CON: Это взрывает количество файлов (и воспринимаемую сложность) в проекте, потому что у каждый класс домена имеет связанный интерфейс.
Вариант 3: Определение хранилища intefaces в SimpleOrder.Domain
ВОЗДЕЙСТВИЯ: Для того, чтобы придать конкретные классы хранилища в слое служб приложений (проект SimpleOrder.ApplicationFacade) из SimpleOrder.ConsoleClient во время выполнения , SimpleOder.ConsoleClient также потребуется ссылка на SimpleOrder.Domain.
PRO: Это также решает Вариант 1
CON: Я пытался избежать ссылок домена слоя из слоя представления непосредственно, потому что теперь уровень представления может знать слишком много о доменном слое. Когда я буду заменять консольное приложение в будущем с помощью WPF или ASP.NET MVC-приложения в будущем, я рискую реализовать второй и последующие реализации уровня представления, пытаясь вызвать методы в модели вместо уровня приложений. (Тем не менее я считаю, что это в варианте 4.)
Вариант 4: Поместите интерфейсы в SimpleOrder.Domain, а затем ссылаться на SimpleOrder.Domain из SimpleOrder.ConsoleClient.
PRO: Устраняет все проблемы, описанные выше.
CON: Это не чувствует себя хорошо, потому что я бы предоставления доступа от слоя представления непосредственно к методам нижнего уровня в слое домена, когда я должен только предоставлять доступ к более высокому уровню коренастого методы в SimpleOrder.ApplicationFacade.
ВОПРОС Я попробовал каждый из них, но остановились на Вариант 4, ОДНАКО, что оставляет неприятный привкус во рту об этом. Есть ли лучший вариант? Я здесь, на правильном пути?
При ближайшем рассмотрении ... варианты 3 и 4 в основном одинаковы. К сожалению. Мне следовало бы получить более подробное доказательство. –