Ваш вопрос содержит пример антишаблона «Локатор служб»:
public class UsesMyService
{
private readonly IMyService _service;
public UsesMyService()
{
_service = SomeClassWithContainer.UnityContainer.Resolve<IMyService>();
}
}
Это принципиально отличается от шаблона внедрения зависимостей из-за направления потоков информации: в приведенном выше примере вы обращаетесь ки запросить для службы, тогда как в приведенном ниже примере вы вручили службу:
public class UsesMyService
{
private readonly IMyService _service;
public UsesMyService(IMyService service)
{
_service = service;
}
}
Этот шаблон, известный как внедрение в конструктор, отделяет UsesMyService
класс из подробностей об окружающей инфраструктуре.Теперь любой, у кого есть реализация IMyService
, может создавать экземпляры UsesMyService
без необходимости конфигурировать центральное статическое расположение.
Как они вообще могут знать, что настраивать?Им потребуется либо исходный код, либо некоторая документация, сообщающая им, что класс зависит от IMyService
.Параметр конструктора четко выражает это требование для потребителей без какой-либо внешней ссылки.
Если вы будете следовать этому шаблону во всех своих библиотеках, вы возьмете на себя ответственность за сборку объектов вплоть до самого внешнего слоя, известного как корень композиции,Это единственное место, обычно класс приложений верхнего уровня, является единственным местом со ссылками на все библиотеки, которые вы используете. Это , где находится контейнер, и никакой другой класс во всем вашем решении не должен ссылаться на него.