Я просматривал предыдущее обсуждение, в котором подробно обсуждалась разница между локатором сервисов и инжектором зависимостей, но все же я не могу этого понять. Могу ли я получить общий ответ без кода?
В чем фактическая разница между локатором службы и внедрением зависимостей?
Ответы (2)
В этом примере кода применяется принцип внедрения зависимостей:
public class UserService : IUserService
{
private IUserRepository repository;
// Constructor taking dependencies
public UserService(IUserRepository repository)
{
this.repository = repository;
}
}
В этом примере кода используется шаблон Service Locator:
public class UserService : IUserService
{
private IUserRepository repository;
public UserService()
{
this.repository = ObjectFactory.GetInstance<IUserRepository>();
}
}
А это реализация шаблона Service Locator:
public class UserService : IUserService
{
private IUserRepository repository;
public UserService(Container container)
{
this.repository = container.GetInstance<IUserRepository>();
}
}
И даже это реализация паттерна Service Locator:
public class UserService : IUserService
{
private IUserRepository repository;
public UserService(IServiceLocator locator)
{
this.repository = locator.GetInstance<IUserRepository>();
}
}
Разница в том, что с внедрением зависимостей вы внедряете все зависимости, которые нужны потребителю, в потребителя (но ничего больше). Идеальный способ внедрения — через конструктор.
С помощью Service Locator вы запрашиваете зависимости из некоторого общего источника. В первом примере это был статический класс ObjectFactory
, а во втором — экземпляр Container
, внедренный в конструктор. Последний фрагмент кода по-прежнему является реализацией шаблона Service Locator, хотя сам контейнер внедряется с использованием внедрения зависимостей.
Есть важные причины, по которым вам следует использовать Dependency Injection вместо Service Locator. Эта статья хорошо объясняет это.
Если вы используете локатор службы, это обычно означает, что вы явно просите какой-либо объект создать для вас другой объект, что обычно считается антишаблоном. Внедрение зависимостей происходит наоборот.
Скажем, у вас есть класс Воин, у которого есть Оружие. Используя локатор службы, вы запросите у локатора службы оружие в конструкторе Warrior.
Используя внедрение зависимостей, оружие будет внедрено в конструктор Warrior без явного запроса.