Внедрение зависимостей, внедрение инжектируемого объекта (сервиса) в новый объект (сущность)

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

  • Инъекции
  • Новинки

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, эти объекты могут запрашивать только другие вводимые объекты в своих конструкторах.

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

Но при написании кода нам часто нужно «внедрить» сервис (внедряемый) в Entity (новый).

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

Как я решил это:

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

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

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

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

person Jupaol    schedule 14.03.2012    source источник
comment
Тесно связано: stackoverflow.com/questions/4835046/   -  person Steven    schedule 14.03.2012
comment
Спасибо, эта ссылка была действительно полезной.   -  person Jupaol    schedule 14.03.2012


Ответы (1)


Но при написании кода нам часто нужно «внедрить» сервис (внедряемый) в Entity (новый).

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

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

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

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

respository.save( cart );

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

person WW.    schedule 08.10.2015