Разве шаблон репозитория в чистой архитектуре не нарушает принцип инверсии зависимостей? - PullRequest
0 голосов
/ 12 марта 2019

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

// project Core
public class CarModel
{
    public string Name { get; set; }

    public void SomeImportantBehavior {}
}

public interface ICarModelRepository 
{
    CarModel FindByName(string name);
    CarModel Add(CarModel carModel);
}

Между тем, другой уровень будет содержать реализацию интерфейса:

// project Infrastructure or Persistence
public class CarModelRepository : ICarModelRepository
{
    public CarModel FindByName(string name)
    {
        return new CarModel { Name = name }; // the implementation is not really important here
    }

    public CarModel Add(CarModel carModel) {
        // somehow persist it here
        return carModel;
    }
}

Итак, у меня есть вопрос: не нарушает ли реализация репозитория принцип DiP? Поскольку это зависит не только от абстракции, но и от конкретной реализации (в данном случае CarModel)?

Другим примером этого является здесь .

P.S. CarModel - это модель предметной области с поведением.

1 Ответ

1 голос
/ 13 марта 2019

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

Чтобы прояснить ситуацию, давайте предположим, что у вас есть класс Controller, который использует ваш Repository. Без DI сначала это выглядело бы так:

class Controller
{
    private CarModelRepository _repository;

    public Controller()
    {
        _repository = new CarModelRepository();
    }

    public void DoSomething()
    {
        //use repository here
    }
}

Глядя в конструктор этого класса, вы можете увидеть, что он создает свою собственную зависимость, выполнив

_repository = new CarModelRepository();

В этом случае Controller содержит зависимость от конкретного CarModelRepository.

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

class Controller
{
    private ICarModelRepository _repository;

    public Controller(ICarModelRepository repository)
    {
        _repository = repository;
    }

    public void DoSomething()
    {
        //use repository here
    }
}

Обратите внимание, что теперь хранилище является ICarModelRepository, который является интерфейсом, а не конкретным типом, и Controller не создает его (как конкретную зависимость), но получает его как абстрактную зависимость (интерфейс) .

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

не нарушает ли реализация репозитория принцип DiP?

Нет, это не так.

...