Внедрение зависимостей, внедрение «внедряемого» объекта (сервиса) в newable (сущность) - PullRequest
7 голосов
/ 14 марта 2012

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

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

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

Но при написании кода нам часто нужно «внедрить» службу (встраиваемую) в сущность (обновляемую)

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

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

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

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

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

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

1 Ответ

3 голосов
/ 08 октября 2015

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

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

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

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

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

respository.save( cart );

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

...