Главная страница   /   12.2. Управление жизненным циклом (Внедрение зависимостей в .NET

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

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

Марк Симан

12.2. Управление жизненным циклом

В главе 8 мы обсуждали процесс управления жизненным циклом, в том числе такие самые универсальные концептуальные стили существования, как Singleton и Transient. Spring.NET поддерживает несколько других стилей существования и позволяет нам конфигурировать жизненные циклы всех объектов. Стили существования, продемонстрированные в таблице 12-3 доступны в виде составляющей пакета.

Примечание

В документации к Spring.NET стили существования называются областями применения объектов.

Реализации Singleton и Transient в Spring.NET аналогичны основным стилям существования, описанным в главе 8, поэтому в данной главе я не буду уделять им много внимания.

Таблица 12-3: Стили существования Spring.NET
Название Комментарии
Singleton Стиль существования по умолчанию.
Prototype Название стиля существования Transient, используемое в рамках Spring.NET. Экземпляры контейнером не отслеживаются.
Request Название стиля существования Web Request Context, используемое в рамках Spring.NET. Корректно только в контексте IApplicationContext.
Session Для одной HTTP-сессии создается один экземпляр. Используйте с осторожностью. Корректно только в контексте IApplicationContext.
Application Расширяет определение одного объекта до жизненного цикла веб-приложения. Корректно только в контексте IApplicationContext.

Примечание

По умолчанию в Spring.NET используется стиль существования Singleton. Этим он отличается от большинства других контейнеров. Как уже обсуждалось в главе 8, Singleton – это самый эффективный, хотя и не всегда безопасный, из всех стилей существования объектов. В Spring.NET эффективность приоритетнее безопасности.

Три веб стиля (Request, Session и Application) тесно связаны между собой соотвествующими IApplicationContexts и не работают с XmlApplicationContext или с XmlObjectFactory, которые мы рассматривали до настоящего момента. Доступные на данный момент реализации настолько сильно связаны с ASP.NET Web Forms, что заставить их работать с ASP.NET MVC довольно трудно. Откровенно говоря, эти стили довольно запутаны и не используются, поэтому в этой главе мы не будем их рассматривать. Предполагается, что в последующих версиях Spring.NET этот вопрос будет модернизирован.

В этой главе я продемонстрирую вам, как конфигурировать области применения объектов на примере стилей Singleton и Transient. Поскольку Spring.NET не поддерживает пользовательские стили существования, эта глава будет краткой. После прочтения этой главы вы сможете использовать стили существования объектов в Spring.NET.

Конфигурирование областей применения

Области применения конфигурируются в качестве составляющей части конфигурации объектов в XML.

Для того чтобы сконфигурировать объект как Transient, необходимо установить атрибуту singleton значение false:

<object id="Sauce" type="SauceBéarnaise" singleton="false" />

Изменив значение атрибута на true, мы сконфигурируем объект как Singleton:

<object id="Sauce" type="SauceBéarnaise" singleton="true" />

Атрибут singleton является необязательным, поскольку стиль Singleton используется по умолчанию, за исключением тех случаев, когда он неявным образом конфигурируется как Singleton. Именно это вы и будете делать далее в этой главе.

Предотвращение утечек памяти

Как и любой другой DI-контейнер Spring.NET создает диаграммы объектов. Однако он не выполняет за нас отслеживание созданных объектов. Он может отслеживать созданные объекты для своих собственных целей, но все это зависит от стиля существования объекта. Например, для реализации области применения Singleton Spring.NET должен хранить ссылку на созданный экземпляр. С другой стороны, область применения Transient не отслеживает объекты, созданные Spring.NET. Как вы уже видели в листингах 8-7 и 8-8, экземпляры объектов создаются и возвращаются без внутреннего сопровождения. Все это имеет некоторые достоинства и преимущества.

Поскольку Spring.NET не держится за экземпляры, риск случайных утечек памяти не велик. При использовании таких контейнеров, как Castle Windsor, утечки памяти гарантированы, если вы забыли вызвать метод Release для всех разрешенных диаграмм объектов. В Spring.NET все не так, поскольку объекты будут автоматически уничтожаться "сборщиком мусора", как только они будут выходить за рамки области применения.

Недостаток заключается в том, что устраняемые объекты нельзя детерминированно уничтожать. Поскольку мы не можем явно высвобождать диаграмму объектов, мы не можем уничтожать любые устранямые объекты. Это означает, что наибольшую значимость приобретает заворачивание устраняемых API в неустраняемые сервисы, что обсуждалось в разделе 6.2.1.

Короче говоря, Spring.NET ведет себя подобающим образом и позволяет объектам уничтожаться "сборщиком мусора", когда они выходят за рамки области применения вашего кода. Но при этом необходимо, чтобы ваши собственные классы также вели себя подобающим образом. Поскольку в вопросе уничтожения любого сервиса мы не можем полагаться на контейнер или код, выполняющий вызов, мы должны продолжать использовать устраняемые объекты в рамках единичных методов.

Эта глава предоставила удивительно краткий обзор областей применения объектов, применяемых в Spring.NET. По этому вопросу особо и нечего сказать. Единственные повсеместно доступные области применения – это Singleton и Transient, тогда как пара остальных областей применения полагается на конкретные реализации IApplicationContext. При конфигурировании объектов мы можем конфигурировать некоторые из них как Singleton, а некоторые – как Transient, и это справедливо даже, когда мы конфигурируем составные реализации одной и той же абстракции. Мы уже рассматривали то, как работать с составными компонентами, поэтому давайте переключим наше внимание в этом направлении.