Using transaction attributes on non-IoC classes with Spring.NET

by timvasil 3/10/2008 6:32:00 PM

Spring.NET 1.1 makes managing transactions straightforward with the TransactionAttribute attribute.  For example:

        [Transaction(TransactionPropagation.Required)]
        public virtual void DoSomething()
        {
            // Do stuff here
        }

The details of what this means and how this works is fully documented.

It works great when you're using IoC features to configure objects.  But what if you want to slap TransactionAttribute on methods of classes you haven't pre-configured and whose lifetime you do not control, say for a methods on a unit test class (i.e. one with a [TestClass] attribute)? 

You can easily get the same kind of support by 1) defining a placeholder object in the Spring configuration, and 2) wrapping objects in proxies on the fly using this placeholder name.

Step 1:  Define a placeholder object

The configuration XML to get transaction attributes to work is a bit, well, verbose, as you can see below.  The red text shows the additions you can add to define a placeholder object called TransactionSupportedType.  You can use any name you wish.  The configuration basically says "objects named TransactionSupportedType should have methods with the TransactionAttribute intercepted."

    <!-- DAO -->
    <object id="Dao"
            type="TestApp.HibernateDao, TestApp"
            singleton="true">
        <property name="SessionFactory" ref="SessionFactory"/>
    </object>

    <!-- Transaction manager -->
    <object id="TransactionManager"
            type="Spring.Data.NHibernate.HibernateTransactionManager, Spring.Data.NHibernate12">
        <property name="DbProvider" ref="Provider"/>
        <property name="SessionFactory" ref="SessionFactory"/>
    </object>

    <!-- Transaction demarcation -->
    <object id="AttributeTransactionAttributeSource"
            type="Spring.Transaction.Interceptor.AttributesTransactionAttributeSource, Spring.Data">
    </object>
    <object id="TransactionInterceptor"
            type="Spring.Transaction.Interceptor.TransactionInterceptor, Spring.Data">
        <property name="TransactionAttributeSource" ref="AttributeTransactionAttributeSource"/>
        <property name="TransactionManager" ref="TransactionManager"/>
    </object>
    <object type="Spring.Transaction.Interceptor.TransactionAttributeSourceAdvisor, Spring.Data"
            autowire="constructor">
        <property name="TransactionInterceptor" ref="TransactionInterceptor"/>
    </object>
    <object id="Interceptors" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
        <property name="ObjectNames">
            <list>
                <value>Dao</value>
                <value>TransactionSupportedType</value>
            </list>
        </property>
        <property name="InterceptorNames">
            <list>
                <value>TransactionInterceptor</value>
            </list>
        </property>
    </object>
    <object id="TransactionSupportedType"/>

Step 2:  Wrap objects in proxies on the fly

Here's where we can easily leverage the AOP engine of Spring.NET to build the proxy we need-on-the fly.  It's as simple as:

MyType testProxy = (MyType)ContextRegistry.GetContext().ConfigureObject(this, "TransactionSupportedType");

This configures the preexisting object of type MyType with the configuration of TransactionSupportedType.  The proxy's public methods with the TransactionAttribute specified will be intercepted appropriately.  Be aware of an important gotcha:  the attribute works with public and/or interface methods only; you cannot use it with protected methods, even if they are marked virtual.  Advice on protected virtual methods may be available in Spring.NET 1.2 where in addition to composition and decorator proxies, inheritance proxies will be supported.

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Spring.NET | AOP

Related posts

Comments are closed

 

About the author

Tim Vasil Tim Vasil
I'm a software engineer living in Cambridge, MA.

E-mail me Send mail

Search

Calendar

<<  September 2010  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

Recent comments