Следует ли считать создание контейнера Unity дорогостоящей операцией с точки зрения ресурсов и времени?

Недавно я начал использовать Unity для внедрения зависимостей в .net. У меня сложилось впечатление, что контейнер Unity, скорее всего, будет одноэлементным или статическим членом класса. Я видел, как другой разработчик использовал его в обработчике запросов, который будет получать много трафика.

Происходит ли какое-то волшебство, которое позволяет каждый раз создавать новый контейнер Unity на низком уровне, или этот код следует реорганизовать, чтобы создать контейнер Unity только один раз?

Этот код является частью класса реализации службы .svc.

public string DoSomeWork(Request request)
{
   var container = new UnityContainer().LoadConfiguration("MyContainer");
   var handler = container.Resolve<RequestHandler>();
   return handler.Handle(request);
}

person ScArcher2    schedule 14.09.2011    source источник
comment
Обычно вы создаете свой DI-контейнер в корне композиции. Не потому, что это дорого, а просто потому, что это имеет смысл в общей схеме DI. Выполнение привязок вне корня композиции обычно приводит к ухудшению дизайна.   -  person Andrew Savinykh    schedule 15.09.2011
comment
Я должен был уточнить, что этот код используется для реализации службы (файл .svc). Я не знаю, можно ли использовать Unity напрямую как часть .svc.   -  person ScArcher2    schedule 15.09.2011


Ответы (2)


Не уверен на 100% с Unity, но с большинством контейнеров IoC создание контейнера и особенно загрузка конфигурации контейнера — достаточно дорогая операция.

Однако я должен задаться вопросом, почему этот разработчик использует контейнер таким образом. В идеале контейнер IoC не должен быть даже статическим или одноэлементным объектом — он должен создаваться только для разрешения объекта верхнего уровня вашего дерева зависимостей, а остальные объекты в вашем приложении должны создаваться автоматически посредством внедрения зависимостей. В случае вашего примера класс, содержащий этот метод, в идеале должен иметь RequestHandler (в идеале интерфейс этого), введенный в него через конструктор, поэтому этому классу не нужно знать о контейнере IoC.

person Paul Kirby    schedule 14.09.2011
comment
Я должен был уточнить, что этот код используется для реализации службы (файл .svc). Я не знаю, можно ли использовать Unity напрямую как часть .svc. - person ScArcher2; 15.09.2011

Это неправильный способ использования контейнера IOC — в основном вы используете его как локатор сервисов , но это приведет к тому, что зависимости от контейнера IOC будут разбросаны по всей кодовой базе.

Что вам нужно сделать, так это иметь одно центральное место в вашей кодовой базе, где разрешаются все зависимости, а затем использовать внедрение зависимостей (DI) для распространения разрешенных конкретных классов по цепочке, то есть с помощью внедрения конструктора. Итак, ваш класс действительно должен выглядеть примерно так:

public class Foo
{
    private readonly IRequestHandler _handler;

    public Foo(IRequestHandler handler)
    {
        _handler = handler;
    }

    public string DoSomeWork(Request request)
    {
        return _handler.Handle(request);
    }
}
person BrokenGlass    schedule 14.09.2011
comment
Я должен был уточнить, что этот код используется для реализации службы (файл .svc). Я не знаю, можно ли использовать Unity напрямую как часть .svc. - person ScArcher2; 15.09.2011