Главная страница   /   8.4. Резюме (Внедрение зависимостей в .NET

Внедрение зависимостей в .NET

Внедрение зависимостей в .NET

Марк Симан

8.4. Резюме

Когда мы применяем инверсию управления к зависимостям, мы инвертируем управление не только над выбором типа, но также над процессом управления жизненным циклом. Когда потребитель больше не создает свои собственные зависимости, он уже не может постановить, когда была создана зависимость, и была ли она разделена с другими потребителями.

Composer'ы могут принять решение, позволяющее множеству потребителей совместно использовать один и тот же экземпляр, или позволяющие каждому потребителю обладать своим собственным экземпляром. Кроме того, в игру вступают более продвинутые стратегии.

Несмотря на то, что Composer'ы отлично управляют тем, когда создаются объекты, управляемая модель памяти .NET подразумевает, что в большинстве случаев они лишь слегка влияют на то, когда разрушаются объекты. Зависимости могут выйти за рамки области применения и быть утилизированы с помощью сборщика мусора. Но особое место отведено компонентам, которые также реализуют IDisposable, поскольку мы должны убедиться, что все неуправляемые ресурсы очищены – иначе наши приложения вскоре начнут испытывать утечку памяти.

Равносильно вызову метода Resolve (или какое название он имеет) мы должны всегда не забывать вызывать метод Release, когда разрешенная диаграмма объектов выходит за рамки области применения. Это дает Composer возможность уничтожить любые устраняемые компоненты, которые становятся неиспользуемыми.

Каждая диаграмма объектов может иметь смесь множества различных стилей существования, и нам, кроме того, нужно следить за тем, являются ли компоненты устраняемыми. Добавьте к этой смеси потоко-безопасность, и станет сложно отслеживать все эти вещи. Именно здесь и расцветает только что распустившийся DI-контейнер, и это одна из причин того, что нам следует использовать DI-контейнер вместо Poor Man's DI.

Каждый из множества доступных DI-контейнеров предлагает свой собственный доступный стиль существования. Некоторые из них поддерживают только несколько стилей существования, другие DI-контейнеры поддерживают большинство или все стили существования, но многие из них предоставляют возможности расширяемости, которые позволяют нам реализовывать свои собственные стили существования.

Самый безопасный стиль существования – Transient, так как экземпляры не делятся с кем-либо еще. Также это самый неэффективный стиль существования, поскольку, скорее всего, в оперативной памяти находится множество экземпляров одного и того же типа.

Наиболее эффективный стиль существования – Singleton, потому что в оперативной памяти находится всего один единственный экземпляр (то есть на один контейнер). Но для этого стиля необходимо, чтобы компонент был потоко-безопасным, поэтому не всегда есть возможность использовать данный стиль существования.

Стили существования Web Request Context и Pooled обеспечивают хорошую альтернативу Singleton и Transient, но в более ограниченных сценариях.

Возможны и более экзотичные стили существования. Стиль существования Future может с первого взгляда казаться отличным способом управления недоступными ресурсами, но как вы увидите в следующей главе, лучше мы обратимся к такой теме, как механизм перехвата.