Чем отличаются Dependency Injection (DI), DI-контейнер и Service Locator?

Какие конкретно различия существуют между этими понятиями? Мне было бы полезно получить более ясное объяснение.
  • 7 марта 2024 г. 16:48
Ответы на вопрос 3
Dependency Injection (DI) - это метод внедрения зависимостей, который позволяет передавать объекты, необходимые для работы класса, через его конструктор, метод или свойства. DI позволяет создавать классы, которые являются независимыми от конкретной реализации их зависимостей, что делает код более гибким и легким для тестирования.

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

Сервис-локатор - это паттерн проектирования, который предоставляет централизованный доступ к сервисам или зависимостям в приложении. В отличие от DI, где зависимости явно передаются классу, при использовании сервис-локатора класс самостоятельно запрашивает необходимые зависимости из централизованного реестра. Этот подход может усложнить понимание структуры приложения и сделать код менее контролируемым и тестируемым.
DI - Внедрение зависимостей. 
DI-container – хранилище зависимостей
Service Locator - механизм, обеспечивающий неявное извлечение "зависимости" (то есть некоторого объекта) из хранилища зависимостей.
DI, Dependecy Injection - это сам процесс внедрения зависимостей (например, когда ты зависимости через конструктор получаешь) 
Пример:
class User
{
    IService _service;
    
    // DI
    User(IService service)
    {
          _service = service;
    }
}


DI-Container - это специальный контейнер, который может необходимую зависимость предоставить. Сначала ты в него регистрируешь все зависимости, а потом вызываешь метод по типу .getService("UserService") и он сам понимает какой сервис ты хочешь, какая у него реализация и как его создать (возможно для него нужны другие зависимости)
Пример
// DI-контейнер
var container = new DependencyContainer();
container.Register(typeof(IService), new ConcreteService());

var service = container.Get<IService>();


Сервис-локатор - это (анти) паттерн, когда, грубо говоря, у тебя есть статический класс этого DI контейнера, к которому обращаются все сервисы. Т.е. вместо того, чтобы использовать тот же самый DI или передавать интерфейс DI контейнера они напрямую обращаются к конкретному DI-контейнеру. Так делать не надо - будут трудности с тестированием, обновлением и всем сопутствующим
Пример
// Сервис-локатор
class ServiceRegistry
{
     IService Service;
     static IService GetService()
     {
           return Service;
     }
}

class User
{
     void DoSomething()
     {
           var service = ServiceRegistry.GetService();
           service.MakeStuff();
     }
}
Похожие вопросы