Внедрение зависимости, внедрение "внедряемого" объекта (сервиса) в newable (сущность)

При написании кода мы должны быть в состоянии идентифицировать две большие группы объектов:

  • Инъекционные
  • Newables

http://www.loosecouplings.com/2011/01/how-to-write-testable-code-overview.html

http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/

  • Инъецируемые объекты - это объекты (сервисы), которые представляют зависимости в своих конструкторах. Эти зависимости обычно разрешаются с помощью контейнера IoC, эти объекты могут запрашивать только другие инъекционные объекты в своих конструкторах.

  • Новизны - это объекты, которые также предоставляют зависимости в своих конструкторах, но newables может запрашивать только другие новые объекты (Entities, Value Objects), еще одна характеристика новых объектов заключается в том, что они не должны содержать ссылку на инъецируемый объект.

Но при написании кода нам часто нужно "внедрить" сервис (инъекционный) в сущность (новый)

Я думал, что, возможно, разоблачение служебной зависимости в новом объекте лучше делать на уровне метода, но это звучит как большая работа... просто думать о разрешении зависимостей каждый раз, когда вызывается метод... Хорошо, это пахнет, как если бы мы использовали анти-шаблон Service Locator

Я решил это следующим образом:

  • Создайте интерфейс с методом, раскрывающим зависимость (в этом методе будет использоваться служба)

  • Создайте метод расширения для интерфейса и поместите его в другое пространство имен, возможно, в другую сборку, и просто оберните вызов исходного метода, разрешающего зависимость, используя локатор службы

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

  • Как вы думаете?
  • Использование локатора службы в методе расширения считается плохой практикой?
  • Как бы вы протестировали вызов метода расширения?

1 ответ

Но при написании кода нам часто нужно "внедрить" сервис (инъекционный) в сущность (новый)

Это не тот случай - если вы обнаружите необходимость сделать это, то в Entity существует некоторая функциональность, которая должна быть в сервисе.

Допустим, ваш новичок ShoppingCart и ваш инъекционный это база данных repository, Вы хотите быть в состоянии сделать это:

// somehow cart already got the repository
cart.save();

Ну, вы делаете это неправильно. Вместо этого вам нужно переключить вещи и сделать:

respository.save( cart );

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

Другие вопросы по тегам