Делает Spring.NET Поддержка Создания Пользовательских Сроков Службы Объектов?
В книге инъекция зависимостей в .NET автор говорит, что Spring.NET не поддерживает создание пользовательских периодов жизни объектов (см. Последний абзац раздела 12.2 [управление временем жизни]).
Хотя я новичок в этой структуре, я думаю, что это не так. Основываясь на моих исследованиях до сих пор, я думаю, что можно определить пользовательское время жизни, реализовав интерфейс ITargetSource, хотя, возможно, этот интерфейс может сделать гораздо больше (например, некоторые предопределенные реализации включают объединение объектов в пул и объекты с возможностью горячей замены и т. д.).
Верно ли мое понимание? Если да,то каковы точные логические шаги для создания и настройки пользовательского жизненного цикла? Если нет, то как можно создать пользовательское время жизни объекта в Spring.NET?
1 ответ:
Хорошо, поэтому я на самом деле задал еще один вопрос здесь и, похоже, ответил на этот самый вопрос в процессе (это один из тех редких случаев, когда вы отвечаете на два ваших собственных вопроса с одним ответом, опубликованным вами). Если вы проследите за этим другим вопросом, вы увидите, что действительно можно определить обычное время жизни в Spring.NET.
Итак, вкратце, пользовательское время жизни в Spring.NET может быть создан путем реализации интерфейса ITargetSource, хотя, возможно, это тонкий интерфейс и может быть использован для выполнения причудливых вещей вокруг создания целей. Уже есть несколько доступных реализаций, включая (но не ограничиваясь):
Интересно, что применение времени жизни к вашим объектам может быть очень разным в зависимости от того, какой срок жизни вы хотите. Все объекты внутри Spring.NET являются синглетными по умолчанию. Чтобы указать объект в качестве прототипа (Spring.NET говорите для переходного процесса), вы устанавливаете singleton= "false" следующим образом:
- SingletonTargetSource (обеспечивает синглетное время жизни)
- PrototypeTargetSource (обеспечивает переходное время жизни)
- ThreadLocalTargetSource (обеспечивает время жизни в области потока)
- SimplePoolTargetSource (обеспечивает объединение объектов)
- HotSwappableTargetSource (предоставляет возможность цели подкачки во время выполнения)
<object id="..." type="..." singleton="false"/>
К сожалению, нет такого удобного свойства для остальных предоставленных жизней (включая ваши пользовательские реализации). Итак, предположим, вы хотите настроить объект с локальной областью видимости потока. Вот как вы это сделаете, используя ProxyFactoryObject:
Опять же, если вы хотите получить те же результаты, что и в приведенной выше конфигурации, но с использованием DefaultAdvisorAutoProxyCreator, вам придется сделать это совершенно другим способом, включая реализацию пользовательского типа, реализующего интерфейс ITargetSourceCreator.<?xml version="1.0" encoding="utf-8"?> <objects xmlns="http://www.springframework.net"> <object id="ConsoleLoggingBeforeAdvisor" type="Spring.Aop.Support.DefaultPointcutAdvisor"> <property name="Advice"> <object type="Spring.Examples.AopQuickStart.ConsoleLoggingBeforeAdvice"/> </property> </object> <object id="ServiceCommandTargetSource" type="Spring.Aop.Target.ThreadLocalTargetSource"> <property name="TargetObjectName" value="ServiceCommandTarget"/> </object> <object id="ServiceCommandTarget" type="Spring.Examples.AopQuickStart.ServiceCommand" singleton="false"/> <object name="ServiceCommand" type="Spring.Aop.Framework.ProxyFactoryObject"> <property name="TargetSource" ref="ServiceCommandTargetSource"/> <property name="InterceptorNames"> <list> <value>ConsoleLoggingBeforeAdvisor</value> </list> </property> </object> </objects>
Вот голая реализация ITargetSourceCreator, которая создает ThreadLocalTargetSourceCreator:
namespace Spring.Examples.AopQuickStart { public class ThreadLocalTargetSourceCreator : AbstractPrototypeTargetSourceCreator, ITargetSourceCreator { private readonly ThreadLocalTargetSource _threadLocalTargetSource; public ThreadLocalTargetSourceCreator() { _threadLocalTargetSource = new ThreadLocalTargetSource(); } protected override AbstractPrototypeTargetSource CreatePrototypeTargetSource(Type objectType, string name, IObjectFactory factory) { return _threadLocalTargetSource; } } }
Наконец, вам нужно использовать следующую конфигурацию, чтобы использовать вышеупомянутый ITargetSourceCreator с DefaultAdvisorAutoProxyCreator для создания экземпляров вашего целевого типа в локальной области потока:
<?xml version="1.0" encoding="utf-8"?> <objects xmlns="http://www.springframework.net" default-autowire="constructor"> <object id="ConsoleLoggingBeforeAdvice" type="Spring.Aop.Support.DefaultPointcutAdvisor"> <property name="Advice"> <object type="Spring.Examples.AopQuickStart.ConsoleLoggingBeforeAdvice" /> </property> </object> <object id="ServiceCommand" type="Spring.Examples.AopQuickStart.ServiceCommand" singleton="false"/> <object type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator"> <property name="CustomTargetSourceCreators"> <list element-type="Spring.Aop.Framework.AutoProxy.ITargetSourceCreator"> <object type="Spring.Examples.AopQuickStart.ThreadLocalTargetSourceCreator"/> </list> </property> </object> </objects>
На мой взгляд, способ настройки времени жизни, отличного от синглтона (по умолчанию) и прототипа, несколько неинтуитивен и определенно не оптимизирован для различных типов реализаций фабрики прокси (ProxyFactoryObject vs. DefaultAdvisorAutoProxyCreator)
В общем, да, Spring.NET поддерживает пользовательские периоды жизни. Если ни один из предопределенных периодов жизни не соответствует вашим требованиям, вы можете создать пользовательский период жизни, реализовав интерфейс ITargetSource и настроив его соответствующим образом.