Короткая версия
Иногда я вижу фрагмент кода, в котором зависимость внедряется в конструктор контроллера, но какие преимущества это дает?
Длинная версия
Предположим, вы видите код, подобный следующему.
//ASP.NET
public class SampleController : Controller
{
private IDependency dependency;
public SampleController(IDependency dependency)
{
this.dependency = dependency;
}
}
Или, если вы предпочитаете PHP, давайте посмотрим на следующий
//PHP with Laravel
namespace App\Http\Controllers;
class SampleController extends Controller
{
private $dependency;
public function __construct(Dependency $dependency)
{
$this->dependency = $dependency;
}
}
Насколько мне известно, внедрение зависимостей предназначено для отделить клиента от его зависимости, так что...
...и т.д.
Однако контроллеры не создаются,
$service = new Service();
$controller = new Controller($service);
//you don't do such a thing, do you?
....и контроллеры не используют функции установки (обычно).
Тем не менее, я все еще вижу этот подход в Интернете, включая документ ASP.NET.
Действительно ли выгодно внедрить зависимость в контроллер, а не создавать экземпляр класса в конструкторе с помощью ключевого слова new? (Если да, то как этот подход улучшит ваш код?)





Хорошо,
Итак, при использовании DI вы обычно внедряете интерфейс в свой контроллер, верно?
Что делать, если вы хотите поменять его реализацию?
Например, у вас есть ISearchApi, в настоящее время вы настроили его в своем коде DI, что реализация ISearchApi — это GoogleApi, теперь вы хотите поменять его на BingApi. Вам не нужно трогать какой-либо из вашего существующего кода, так как он весь абстрагирован за интерфейсом. Это часть Принцип инверсии зависимости.
Что, если ваша реализация BingApi также ожидает другой класс в своем конструкторе? и этот класс также ожидает больше классов в своем конструкторе, например:
new BingApi(new BingControls(new Api(new HttpClient, "ApiKey")));
Это будет очень сложно поддерживать в будущем, где, если бы он был правильно настроен в вашем контейнере DI, вам не нужно было бы беспокоиться об этом.
Другой причиной может быть модульное тестирование. Я не собираюсь вдаваться в дебаты о том, что контроллеры должны делать в отношении логики. Но было бы намного сложнее провести модульное тестирование контроллера, ожидающего конкретной реализации, особенно если эта реализация вызывает какие-либо службы/базы данных. Не было бы никакого способа издеваться над этим, поскольку контроллеры просто new придумывают это.
Единственный недостаток, который я вижу во внедрении зависимостей, заключается в том, что при запуске приложения приходится писать немного больше кода. Но это очень незначительно по сравнению с предлагаемыми преимуществами.
Что вы имеете в виду "контроллеры не создаются"? Вы можете не писать этот код явно, если только вы, например. обновляя один в тесте, но они будут абсолютно созданы (через контейнер DI) во время работы приложения. Как вы думаете, почему значение DI в классах контроллеров отличается от значения DI где-либо еще?