# Aspect Oriented Programming with Spring.NET

## Introduction

Aspect-Oriented Programming (AOP) complements OOP by providing another way of thinking about program structure. Whereas OO decomposes applications into a hierarchy of objects, AOP decomposes programs into aspects or concerns. This enables the modularization of concerns such as transaction management that would otherwise cut across multiple objects (such concerns are often termed crosscutting concerns).

One of the key components of Spring.NET is the AOP framework. While the Spring.NET IoC container does not depend on AOP, meaning you don't need to use AOP if you don't want to, AOP complements Spring.NET IoC to provide a very capable middleware solution.

AOP is used in Spring.NET:

- To provide declarative enterprise services, especially as a replacement for COM+ declarative services. The most important such service is declarative transaction management, which builds on Spring.NET's transaction abstraction. This functionality is planed for an upcoming release of Spring.NET

- To allow users to implement custom aspects, complementing their use of OOP with AOP.

Thus you can view Spring.NET AOP as either an enabling technology that allows Spring.NET to provide declarative transaction management without COM+; or use the full power of the Spring.NET AOP framework to implement custom aspects.

For those who would like to hit the ground running and start exploring how to use Spring's AOP functionality, head on over to .

### AOP concepts

Let us begin by defining some central AOP concepts. These terms are not Spring.NET-specific. Unfortunately, AOP terminology is not particularly intuitive. However, it would be even more confusing if Spring.NET used its own terminology.

- Aspect: A modularization of a concern for which the implementation might otherwise cut across multiple objects. Transaction management is a good example of a crosscutting concern in enterprise applications. Aspects are implemented using Spring.NET as Advisors or interceptors.

- Joinpoint: Point during the execution of a program, such as a method invocation or a particular exception being thrown.

- Advice: Action taken by the AOP framework at a particular joinpoint. Different types of advice include "around," "before" and "throws" advice. Advice types are discussed below. Many AOP frameworks, including Spring.NET, model an advice as an interceptor, maintaining a chain of interceptors "around" the joinpoint.

- Pointcut: A set of joinpoints specifying when an advice should fire. An AOP framework must allow developers to specify pointcuts: for example, using regular expressions.

- Introduction: Adding methods or fields to an advised class. Spring.NET allows you to introduce new interfaces to any advised object. For example, you could use an introduction to make any object implement an `IAuditable` interface, to simplify the tracking of changes to an object's state.

- Target object: Object containing the joinpoint. Also referred to as advised or proxied object.

- AOP proxy: Object created by the AOP framework, including advice. In Spring.NET, an AOP proxy is a dynamic proxy that uses IL code generated at runtime.

- Weaving: Assembling aspects to create an advised object. This can be done at compile time (using the Gripper-Loom.NET compiler, for example), or at runtime. Spring.NET performs weaving at runtime.

Different advice types include:

- Around advice: Advice that surrounds a joinpoint such as a method invocation. This is the most powerful kind of advice. Around advice will perform custom behaviour before and after the method invocation. They are responsible for choosing whether to proceed to the joinpoint or to shortcut executing by returning their own return value or throwing an exception.

- Before advice: Advice that executes before a joinpoint, but which does not have the ability to prevent execution flow proceeding to the joinpoint (unless it throws an exception).

- Throws advice: Advice to be executed if a method throws an exception. Spring.NET provides strongly typed throws advice, so you can write code that catches the exception (and subclasses) you're interested in, without needing to cast from Exception.

- After returning advice: Advice to be executed after a joinpoint completes normally: for example, if a method returns without throwing an exception.

Spring.NET provides a full range of advice types. We recommend that you use the least powerful advice type that can implement the required behaviour. For example, if you need only to update a cache with the return value of a method, you are better off implementing an after returning advice than an around advice, although an around advice can accomplish the same thing. Using the most specific advice type provides a simpler programming model with less potential for errors. For example, you don't need to invoke the `proceed()` method on the `IMethodInvocation` used for around advice, and hence can't fail to invoke it.

The pointcut concept is the key to AOP, distinguishing AOP from older technologies offering interception. Pointcuts enable advice to be targeted independently of the OO hierarchy. For example, an around advice providing declarative transaction management can be applied to a set of methods spanning multiple objects. Thus pointcuts provide the structural element of AOP.

### Spring.NET AOP capabilities

Spring.NET AOP is implemented in pure C#. There is no need for a special compilation process - all weaving is done at runtime. Spring.NET AOP does not need to control or modify the way in which assemblies are loaded, nor does it rely on unmanaged APIs, and is thus suitable for use in any CLR environment.

Spring.NET currently supports interception of method invocations. Field interception is not implemented, although support for field interception could be added without breaking the core Spring.NET AOP APIs.

Spring.NET provides classes to represent pointcuts and different advice types. Spring.NET uses the term advisor for an object representing an aspect, including both an advice and a pointcut targeting it to specific joinpoints.

Different advice types are `IMethodInterceptor` (from the AOP Alliance interception API); and the advice interfaces defined in the `Spring.Aop` namespace. All advices must implement the `AopAlliance.Aop.IAdvice` tag interface. Advices supported out the box are `IMethodInterceptor` ; `IThrowsAdvice`; `IBeforeAdvice`; and `IAfterReturningAdvice`. We'll discuss advice types in detail below.

Spring.NET provides a .NET translation of the Java interfaces defined by the AOP Alliance . Around advice must implement the AOP Alliance `AopAlliance.Interceptr.IMethodInterceptor` interface. Whilst there is wide support for the AOP Alliance in Java, Spring.NET is currently the only .NET AOP framework that makes use of these interfaces. In the short term, this will provide a consistent programming model for those doing development in both .NET and Java, and in the longer term, we hope to see more .NET projects adopt the AOP Alliance interfaces.

### AOP Proxies in Spring.NET

Spring.NET generates AOP proxies at runtime using classes from the System.Reflection.Emit namespace to create necessary IL code for the proxy class. This results in proxies that are very efficient and do not impose any restrictions on the inheritance hierarchy.

Another common approach to AOP proxy implementation in .NET is to use ContextBoundObject and the .NET remoting infrastructure as an interception mechanism. We are not very fond of ContextBoundObject approach because it requires classes that need to be proxied to inherit from the ContextBoundObject either directly or indirectly. In our opinion this an unnecessary restriction that influences how you should design your object model and also excludes applying AOP to "3rd party" classes that are not under your direct control. Context-bound proxies are also an order of magnitude slower than IL-generated proxies, due to the overhead of the context switching and .NET remoting infrastructure.

Spring.NET AOP proxies are also "smart" - in that because proxy configuration is known during proxy generation, the generated proxy can be optimized to invoke target methods via reflection only when necessary (i.e. when there are advices applied to the target method). In all other cases the target method will be called directly, thus avoiding performance hit caused by the reflective invocation.

Finally, Spring.NET AOP proxies will never return a raw reference to a target object. Whenever a target method returns a raw reference to a target object (i.e. "return this;"), AOP proxy will recognize what happened and will replace the return value with a reference to itself instead.

The current implementation of the AOP proxy generator uses object composition to delegate calls from the proxy to a target object, similar to how you would implement a classic Decorator pattern. This means that classes that need to be proxied have to implement one or more interfaces, which is in our opinion not only a less-intruding requirement than ContextBoundObject inheritance requirements, but also a good practice that should be followed anyway for the service classes that are most common targets for AOP proxies.

In a future release we will implement proxies using inheritance, which will allow you to proxy classes without interfaces as well and will remove some of the remaining raw reference issues that cannot be solved using composition-based proxies.

## Pointcut API in Spring.NET

Let's look at how Spring.NET handles the crucial pointcut concept.

### Concepts

Spring.NET's pointcut model enables pointcut reuse independent of advice types. It's possible to target different advice using the same pointcut.

The `Spring.Aop.IPointcut` interface is the central interface, used to target advices to particular types and methods. The complete interface is shown below:

    public interface IPointcut
    {
        ITypeFilter TypeFilter { get; }

        IMethodMatcher MethodMatcher { get; }
    }

Splitting the `IPointcut` interface into two parts allows reuse of type and method matching parts, and fine-grained composition operations (such as performing a "union" with another method matcher).

The `ITypeFilter` interface is used to restrict the pointcut to a given set of target classes. If the `Matches()` method always returns true, all target types will be matched:

    public interface ITypeFilter
    {
        bool Matches(Type type);
    }

The `IMethodMatcher` interface is normally more important. The complete interface is shown below:

    public interface IMethodMatcher
    {
        bool IsRuntime { get; }

        bool Matches(MethodInfo method, Type targetType);

        bool Matches(MethodInfo method, Type targetType, object[] args);
    }

The `Matches(MethodInfo, Type)` method is used to test whether this pointcut will ever match a given method on a target type. This evaluation can be performed when an AOP proxy is created, to avoid the need for a test on every method invocation. If the 2-argument matches method returns true for a given method, and the `IsRuntime` property for the `IMethodMatcher` returns true, the 3-argument matches method will be invoked on every method invocation. This enables a pointcut to look at the arguments passed to the method invocation immediately before the target advice is to execute.

Most `IMethodMatchers` are static, meaning that their `IsRuntime` property returns false. In this case, the 3-argument `Matches` method will never be invoked.

### Operations on pointcuts

Spring.NET supports operations on pointcuts: notably, union and intersection.

Union means the methods that either pointcut matches.

Intersection means the methods that both pointcuts match.

Union is usually more useful.

Pointcuts can be composed using the static methods in the Spring.Aop.Support.Pointcuts class, or using the ComposablePointcut class in the same namespace.

### Convenience pointcut implementations

Spring.NET provides several convenient pointcut implementations. Some can be used out of the box; others are intended to be subclassed in application-specific pointcuts.

#### Static pointcuts

Static pointcuts are based on method and target class, and cannot take into account the method's arguments. Static pointcuts are sufficient--and best--for most usages. It's possible for Spring.NET to evaluate a static pointcut only once, when a method is first invoked: after that, there is no need to evaluate the pointcut again with each method invocation.

Let's consider some static pointcut implementations included with Spring.NET.

##### Regular expression pointcuts

One obvious way to specify static pointcuts is using regular expressions. Several AOP frameworks besides Spring.NET make this possible. The `Spring.Aop.Support.SdkRegularExpressionMethodPointcut` class is a generic regular expression pointcut, that uses the regular expression classes from the .NET BCL.

Using this class, you can provide a list of pattern Strings. If any of these is a match, the pointcut will evaluate to true (so the result is effectively the union of these pointcuts.). The matching is done against the full class name so you can use this pointcut if you would like to apply advice to all the classes in a particular namespace.

The usage is shown below:

    <object id="settersAndAbsquatulatePointcut"
        type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
        <property name="patterns">
            <list>
                <value>.*set.*</value>
                <value>.*absquatulate</value>
            </list>
        </property>
    </object>

As a convenience, Spring provides the `RegularExpressionMethodPointcutAdvisor` class that allows us to reference an `IAdvice` instance as well as defining the pointcut rules (remember that an `IAdvice` instance can be an interceptor, before advice, throws advice etc.) This simplifies wiring, as the one object serves as both pointcut and advisor, as shown below:

    <object id="settersAndAbsquatulateAdvisor"
        type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">
        <property name="advice">
            <ref local="objectNameOfAopAllianceInterceptor"/>
        </property>
        <property name="patterns">
            <list>
                <value>.*set.*</value>
                <value>.*absquatulate</value>
            </list>
        </property>
    </object>

The `RegularExpressionMethodPointcutAdvisor` class can be used with any `Advice` type.

If you only have one pattern you can use the property name

pattern

and specify a single value instead of using the property name

patterns

and specifying a list.

You may also specify a `Regex` object from the `System.Text.RegularExpressions` namespace. The built in `RegexConverter` class will perform the conversion. See for more information on Spring's build in type converters. The Regex object is created as any other object within the IoC container. Using an inner-object definition for the Regex object is a handy way to keep the definition close to the PointcutAdvisor declaration. Note that the class `SdkRegularExpressionMethodPointcut` has a `DefaultOptions` property to set the regular expression options if they are not explicitly specified in the constructor.

##### Attribute pointcuts

Pointcuts can be specified by matching an attribute type that is associated with a method. Advice associated with this pointcut can then read the metadata associated with the attribute to configure itself. The class `AttributeMatchMethodPointcut` provides this functionality. Sample usage that will match all methods that have the attribute `Spring.Attributes.CacheAttribute` is shown below.

    <object id="cachePointcut" type="Spring.Aop.Support.AttributeMatchMethodPointcut, Spring.Aop">
        <property name="Attribute" value="Spring.Attributes.CacheAttribute, Spring.Core"/>
    </object>

This can be used with a `DefaultPointcutAdvisor` as shown below

    <object id="cacheAspect" type="Spring.Aop.Support.DefaultPointcutAdvisor, Spring.Aop">
      <property name="Pointcut">
          <object type="Spring.Aop.Support.AttributeMatchMethodPointcut, Spring.Aop">
              <property name="Attribute" value="Spring.Attributes.CacheAttribute, Spring.Core"/>
          </object>
      </property>
      <property name="Advice" ref="aspNetCacheAdvice"/>
    </object>

where aspNetCacheAdvice is an implementation of an `IMethodInterceptor` that caches method return values. See the SDK docs for `Spring.Aop.Advice.CacheAdvice` for more information on this particular advice.

As a convenience the class `AttributeMatchMethodPointcutAdvisor` is provided to defining an attribute based Advisor as a somewhat shorter alternative to using the generic DefaultPointcutAdvisor. An example is shown below.

    <object id="AspNetCacheAdvice" type="Spring.Aop.Support.AttributeMatchMethodPointcutAdvisor, Spring.Aop">
       <property name="advice">
          <object type="Aspect.AspNetCacheAdvice, Aspect"/>
       </property>
       <property name="attribute" value="Framework.AspNetCacheAttribute, Framework" />
    </object>

#### Dynamic Pointcuts

Dynamic pointcuts are costlier to evaluate than static pointcuts. They take into account method arguments, as well as static information. This means that they must be evaluated with every method invocation; the result cannot be cached, as arguments will vary.

The main example is the `control flow` pointcut.

##### Control Flow Pointcuts

Spring.NET control flow pointcuts are conceptually similar to AspectJ cflow pointcuts, although less powerful. (There is currently no way to specify that a pointcut executes below another pointcut.). A control flow pointcut is dynamic because it is evaluated against the current call stack for each method invocation. For example, if method ClassA.A() calls ClassB.B() then the execution of ClassB.B() has occurred in ClassA.A()'s control flow. A control flow pointcut allows advice to be applied to the method ClassA.A() but only when called from ClassB.B() and not when ClassA.A() is executed from another call stack. Control flow pointcuts are specified using the `Spring.Aop.Support.ControlFlowPointcut` class.

Control flow pointcuts are significantly more expensive to evaluate at runtime than even other dynamic pointcuts.

When using control flow point cuts some attention should be paid to the fact that at runtime the JIT compiler can inline the methods, typically for increased performance, but with the consequence that the method no longer appears in the current call stack. This is because inlining takes the callee's IL code and inserts it into the caller's IL code effectively removing the method call. The information returned from `System.Diagnostics.StackTrace`, used in the implementation of `ControlFlowPointcut` is subject to these optimizations and therefore a control flow pointcut will not match if the method has been inlined.

Generally speaking, a method will be a candidate for inlining when its code is 'small', just a few lines of code (less than 32 bytes of IL). For some interesting reading on this process read David Notario's blog entries (JIT Optimizations I and JIT Optimizations II). Additionally, when an assembly is compiled with a Release configuration the assembly metadata instructs the CLR to enable JIT optimizations. When compiled with a Debug configuration the CLR will disable (some?) these optimizations. Empirically, method inlining is turned off in a Debug configuration.

The way to ensure that your control flow pointcut will not be overlooked because of method inlining is to apply the `System.Runtime.CompilerServices.MethodImplAttribute` attribute with the value `MethodImplOptions.NoInlining`. In this (somewhat artificial) simple example, if the code is compiled in release mode it will not match a control flow pointcut for the method "GetAge".

    public int GetAge(IPerson person)
    {
        return person.GetAge();
    }

However, applying the attributes as shown below will prevent the method from being inlined even in a release build.

    [MethodImpl(MethodImplOptions.NoInlining)]
    public int GetAge(IPerson person)
    {
        return person.GetAge();
    }

### Custom pointcuts

Because pointcuts in Spring.NET are .NET types, rather than language features (as in AspectJ) it is possible to declare custom pointcuts, whether static or dynamic. However, there is no support out of the box for the sophisticated pointcut expressions that can be coded in the AspectJ syntax. However, custom pointcuts in Spring.NET can be as arbitrarily complex as any object model.

Spring.NET provides useful pointcut superclasses to help you to implement your own pointcuts.

Because static pointcuts are the most common and generally useful pointcut type, you'll probably subclass `StaticMethodMatcherPointcut`, as shown below. This requires you to implement just one abstract method (although it is possible to override other methods to customize behaviour):

    public class TestStaticPointcut : StaticMethodMatcherPointcut {

        public override bool Matches(MethodInfo method, Type targetType) {
            // return true if custom criteria match
        }
    }

## Advice API in Spring.NET

Let's now look at how Spring.NET AOP handles advice.

### Advice Lifecycle

Spring.NET advices can be shared across all advised objects, or unique to each advised object. This corresponds to per-class or per-instance advice.

Per-class advice is used most often. It is appropriate for generic advice such as transaction advisors. These do not depend on the state of the proxied object or add new state; they merely act on the method and arguments.

Per-instance advice is appropriate for introductions, to support mixins. In this case, the advice adds state to the proxied object.

It's possible to use a mix of shared and per-instance advice in the same AOP proxy.

### Advice types

Spring.NET provides several advice types out of the box, and is extensible to support arbitrary advice types. Let us look at the basic concepts and standard advice types.

#### Interception Around Advice

The most fundamental advice type in Spring.NET is interception around advice.

Spring.NET is compliant with the AOP Alliance interface for around advice using method interception. Around advice is implemented using the following interface:

    public interface IMethodInterceptor : IInterceptor
    {
        object Invoke(IMethodInvocation invocation);
    }

The `IMethodInvocation` argument to the `Invoke()` method exposes the method being invoked; the target joinpoint; the AOP proxy; and the arguments to the method. The `Invoke()` method should return the invocation's result: the return value of the joinpoint.

A simple `IMethodInterceptor` implementation looks as follows:

    public class DebugInterceptor : IMethodInterceptor {

        public object Invoke(IMethodInvocation invocation) {
            Console.WriteLine("Before: invocation=[{0}]", invocation);
            object rval = invocation.Proceed();
            Console.WriteLine("Invocation returned");
            return rval;
        }
    }

Note the call to the IMethodInvocation's `Proceed()` method. This proceeds down the interceptor chain towards the joinpoint. Most interceptors will invoke this method, and return its return value. However, an IMethodInterceptor, like any around advice, can return a different value or throw an exception rather than invoke the `Proceed()` method. However, you don't want to do this without good reason!

#### Before advice

A simpler advice type is a before advice. This does not need an `IMethodInvocation` object, since it will only be called before entering the method.

The main advantage of a before advice is that there is no need to invoke the `Proceed()`method, and therefore no possibility of inadvertently failing to proceed down the interceptor chain.

The `IMethodBeforeAdvice` interface is shown below.

    public interface IMethodBeforeAdvice : IBeforeAdvice
    {
        void Before(MethodInfo method, object[] args, object target);
    }

Note the return type is `void`. Before advice can insert custom behaviour before the joinpoint executes, but cannot change the return value. If a before advice throws an exception, this will abort further execution of the interceptor chain. The exception will propagate back up the interceptor chain. If it is unchecked, or on the signature of the invoked method, it will be passed directly to the client; otherwise it will be wrapped in an unchecked exception by the AOP proxy.

An example of a before advice in Spring.NET, which counts all methods that return normally:

    public class CountingBeforeAdvice : IMethodBeforeAdvice {

        private int count;

        public void Before(MethodInfo method, object[] args, object target) {
            ++count;
        }

        public int Count  {
            get { return count; }
        }
    }

#### Throws advice

Throws advice is invoked after the return of the joinpoint if the joinpoint threw an exception. The `Spring.Aop.IThrowsAdvice` interface does not contain any methods: it is a tag interface identifying that the implementing advice object implements one or more typed throws advice methods. These throws advice methods must be of the form:

    AfterThrowing([MethodInfo method, Object[] args, Object target], Exception subclass)

Throws-advice methods must be named `'AfterThrowing'`. The return value will be ignored by the Spring.NET AOP framework, so it is typically `void`. With regard to the method arguments, only the last argument is required. Thus there are exactly one or four arguments, depending on whether the advice method is interested in the method, method arguments and the target object.

The following method snippets show examples of throws advice.

This advice will be invoked if a `RemotingException` is thrown (including subclasses):

    public class RemoteThrowsAdvice : IThrowsAdvice {

        public void AfterThrowing(RemotingException ex) {
            // Do something with remoting exception
        }
    }

The following advice is invoked if a `SqlException` is thrown. Unlike the above advice, it declares 4 arguments, so that it has access to the invoked method, method arguments and target object:

    public class SqlExceptionThrowsAdviceWithArguments : IThrowsAdvice {

        public void AfterThrowing(MethodInfo method, object[] args, object target, SqlException ex) {
            // Do something will all arguments
        }
    }

The final example illustrates how these two methods could be used in a single class, which handles both `RemotingException` and `SqlException`. Any number of throws advice methods can be combined in a single class, as can be seen in the following example.

    public class CombinedThrowsAdvice : IThrowsAdvice {

        public void AfterThrowing(RemotingException ex)  {
            // Do something with remoting exception
        }

        public void AfterThrowing(MethodInfo method, object[] args, object target, SqlException ex) {
            // Do something will all arguments
        }
    }

Finally, it is worth stating that throws advice is only applied to the actual exception being thrown. What does this mean? Well, it means that if you have defined some throws advice that handles `RemotingException`s, the applicable `AfterThrowing` method will only be invoked if the type of the thrown exception is `RemotingException`... if a `RemotingException` has been thrown and subsequently wrapped inside another exception before the exception bubbles up to the throws advice interceptor, then the throws advice that handles `RemotingException`s will never be called. Consider a business method that is advised by throws advice that handles `RemotingException`s; if during the course of a method invocation said business method throws a RemoteException... and subsequently wraps said `RemotingException` inside a business-specific `BadConnectionException` (see the code snippet below) before throwing the exception, then the throws advice will never be able to respond to the `RemotingException`... because all the throws advice sees is a `BadConnectionException`. The fact that the `RemotingException` is wrapped up inside the `BadConnectionException` is immaterial.

    public void BusinessMethod()
        {
            try
            {
                // do some business operation...
            }
            catch (RemotingException ex)
            {
                throw new BadConnectionException("Couldn't connect.", ex);
            }
        }

Please note that throws advice can be used with any pointcut.

#### After Returning advice

An after returning advice in Spring.NET must implement the `Spring.Aop.IAfterReturningAdvice` interface, shown below:

    public interface IAfterReturningAdvice : IAdvice
    {
      void AfterReturning(object returnValue, MethodBase method, object[] args, object target);
    }

An after returning advice has access to the return value (which it cannot modify), invoked method, methods arguments and target.

The following after returning advice counts all successful method invocations that have not thrown exceptions:

    public class CountingAfterReturningAdvice : IAfterReturningAdvice {
        private int count;

        public void AfterReturning(object returnValue, MethodBase m, object[] args, object target) {
            ++count;
        }

        public int Count  {
            get { return count; }
        }
    }

This advice doesn't change the execution path. If it throws an exception, this will be thrown up the interceptor chain instead of the return value.

Please note that after-returning advice can be used with any pointcut.

#### Advice Ordering

When multiple pieces of advice want to run on the same joinpoint the precedence is determined by having the advice implement the IOrdered interface or by specifying order information on an advisor.

#### Introduction advice

Spring.NET allows you to add new methods and properties to an advised class. This would typically be done when the functionality you wish to add is a crosscutting concern and want to introduce this functionality as a change to the static structure of the class hierarchy. For example, you may want to cast objects to the introduction interface in your code. Introductions are also a means to emulate multiple inheritance.

Introduction advice is defined by using a normal interface declaration that implements the tag interface `IAdvice`.

The need for implementing this marker interface will likely be removed in future versions.

As an example, consider the interface `IAuditable` that describes the last modified time of an object.

    public interface IAuditable : IAdvice
    {
        DateTime LastModifiedDate
        {
            get;
            set;
        }
    }

where

    public interface IAdvice
    {
    }

Access to the advised object can be obtained by implementing the interface `ITargetAware`

    public interface ITargetAware
    {
      IAopProxy TargetProxy
      {
        set;
      }
    }

with the `IAopProxy` reference providing a layer of indirection through which the advised object can be accessed.

    public interface IAopProxy
    {
      object GetProxy();
    }

A simple class that demonstrates this functionality is shown below.

    public interface IAuditable : IAdvice, ITargetAware
    {
        DateTime LastModifiedDate
        {
            get;
            set;
        }
    }

A class that implements this interface is shown below.

    public class AuditableMixin : IAuditable
    {
        private DateTime date;
        private IAopProxy targetProxy;

        public AuditableMixin()
        {
          date = new DateTime();
        }

        public DateTime LastModifiedDate
        {
           get { return date; }
           set { date = value; }
        }

        public IAopProxy TargetProxy
        {
           set { targetProxy = value; }
        }
    }

Introduction advice is not associated with a pointcut, since it applies at the class and not the method level. As such, introductions use their own subclass of the interface `IAdvisor`, namely `IIntroductionAdvisor`, to specify the types that the introduction can be applied to.

    public interface IIntroductionAdvisor : IAdvisor
    {
        ITypeFilter TypeFilter { get; }

        Type[] Interfaces { get; }

        void ValidateInterfaces();
    }

The `TypeFilter` property returns the filter that determines which target classes this introduction should apply to.

The `Interfaces` property returns the interfaces introduced by this advisor.

The `ValidateInterfaces()` method is used internally to see if the introduced interfaces can be implemented by the introduction advice.

Spring.NET provides a default implementation of this interface (the `DefaultIntroductionAdvisor` class) that should be sufficient for the majority of situations when you need to use introductions. The most simple implementation of an introduction advisor is a subclass that simply passes a new instance the base constructor. Passing a new instance is important since we want a new instance of the mixin classed used for each advised object.

    public class AuditableAdvisor : DefaultIntroductionAdvisor
    {
      public AuditableAdvisor() : base(new AuditableMixin())
      {
      }
    }

Other constructors let you explicitly specify the interfaces of the class that will be introduced. See the SDK documentation for more details.

We can apply this advisor Programatically, using the `IAdvised.AddIntroduction(),` method, or (the recommended way) in XML configuration using the `IntroductionNames` property on `ProxyFactoryObject`, which will be discussed later.

## Advisor API in Spring.NET

In Spring.NET, an advisor is a modularization of an aspect. Advisors typically incorporate both an advice and a pointcut.

Apart from the special case of introductions, any advisor can be used with any advice. The `Spring.Aop.Support.DefaultPointcutAdvisor` class is the most commonly used advisor implementation. For example, it can be used with a `IMethodInterceptor`, `IBeforeAdvice` or `IThrowsAdvice` and any pointcut definition.

Other convenience implementations provided are: `AttributeMatchMethodPointcutAdvisor` shown in usage previously in for use with attribute based pointcuts. `RegularExpressionMethodPointcutAdvisor` that will apply pointcuts based on the matching a regular expression to method names.

It is possible to mix advisor and advice types in Spring.NET in the same AOP proxy. For example, you could use a interception around advice, throws advice and before advice in one proxy configuration: Spring.NET will automatically create the necessary interceptor chain.

## Using the ProxyFactoryObject to create AOP proxies

If you're using the Spring.NET IoC container for your business objects - generally a good idea - you will want to use one of Spring.NET's AOP-specific `IFactoryObject` implementations (remember that a factory object introduces a layer of indirection, enabling it to create objects of a different type - ).

The basic way to create an AOP proxy in Spring.NET is to use the `Spring.Aop.Framework.ProxyFactoryObject` class. This gives complete control over ordering and application of the pointcuts and advice that will apply to your business objects. However, there are simpler options that are preferable if you don't need such control.

### Basics

The `ProxyFactoryObject`, like other Spring.NET `IFactoryObject` implementations, introduces a level of indirection. If you define a `ProxyFactoryObject` with name `foo`, what objects referencing `foo` see is not the `ProxyFactoryObject` instance itself, but an object created by the `ProxyFactoryObject's` implementation of the `GetObject()` method. This method will create an AOP proxy wrapping a target object.

One of the most important benefits of using a `ProxyFactoryObject` or other IoC-aware classes that create AOP proxies, is that it means that advice and pointcuts can also be managed by IoC. This is a powerful feature, enabling certain approaches that are hard to achieve with other AOP frameworks. For example, an advice may itself reference application objects (besides the target, which should be available in any AOP framework), benefiting from all the pluggability provided by Dependency Injection.

### ProxyFactoryObject Properties

Like most `IFactoryObject` implementations provided with Spring.NET, the `ProxyFactoryObject` is itself a Spring.NET configurable object. Its properties are used to:

- Specify the target object that is to be proxied.

- Specify the advice that is to be applied to the proxy.

Some key properties are inherited from the `Spring.Aop.Framework.ProxyConfig` class: this class is the superclass for all AOP proxy factories in Spring.NET. Some of the key properties include:

- `ProxyTargetType`: a boolean value that should be set to true if the target class is to be proxied directly, as opposed to just proxying the interfaces exposed on the target class.

- `Optimize`: whether to apply aggressive optimization to created proxies. Don't use this setting unless you understand how the relevant AOP proxy handles optimization. The exact meaning of this flag will differ between proxy implementations and will generally result in a trade off between proxy creation time and runtime performance. Optimizations may be ignored by certain proxy implementations and may be disabled silently based on the value of other properties such as `ExposeProxy`.

- `IsFrozen`: whether advice changes should be disallowed once the proxy factory has been configured. The default is false.

- `ExposeProxy`: whether the current proxy should be exposed via the `AopContext` so that it can be accessed by the target. (It's available via the `IMethodInvocation` without the need for the `AopContext`.) If a target needs to obtain the proxy and `ExposeProxy` is `true`, the target can use the `AopContext.CurrentProxy` property.

- `AopProxyFactory`: the implementation of `IAopProxyFactory` to use when generating a proxy. Offers a way of customizing whether to use remoting proxies, IL generation or any other proxy strategy. The default implementation will use IL generation to create composition-based proxies.

Other properties specific to the `ProxyFactoryObject` class include:

- `ProxyInterfaces`: the array of `string` interface names we're proxying.

- `InterceptorNames`: `string` array of `IAdvisor`, interceptor or other advice names to apply. Ordering is significant... first come, first served that is. The first interceptor in the list will be the first to be able to interceptor the invocation (assuming it concerns a regular MethodInterceptor or BeforeAdvice).

  The names are object names in the current container, including objectnames from container hierarchies. You can't mention object references here since doing so would result in the `ProxyFactoryObject` ignoring the singleton setting of the advise.

- `IntroductionNames`: The names of objects in the container that will be used as introductions to the target object. If the object referred to by name does not implement the `IIntroductionAdvisor` it will be passed to the default constructor of `DefaultIntroductionAdvisor` and all of the objects interfaces will be added to the target object. Objects that implement the `IIntroductionAdvisor` interface will be used as is, giving you a finer level of control over what interfaces you may want to expose and the types for which they will be matched against.

- `IsSingleton`: whether or not the factory should return a single proxy object, no matter how often the `GetObject()` method is called. Several `IFactoryObject` implementations offer such a method. The default value is `true`. If you would like to be able to apply advice on a per-proxy object basis, use a `IsSingleton` value of `false` and a `IsFrozen` value of `false`. If you want to use stateful advice--for example, for stateful mixins--use prototype advices along with a `IsSingleton` value of `false`.

### Proxying Interfaces

Let's look at a simple example of `ProxyFactoryObject` in action. This example involves:

- A target object that will be proxied. This is the "personTarget" object definition in the example below.

- An `IAdvisor` and an `IInterceptor` used to provide advice.

- An AOP proxy object definition specifying the target object (the personTarget object) and the interfaces to proxy, along with the advices to apply.

    <object id="personTarget" type="MyCompany.MyApp.Person, MyCompany">
        <property name="name" value="Tony"/>
        <property name="age" value="51"/>
    </object>

    <object id="myCustomInterceptor" type="MyCompany.MyApp.MyCustomInterceptor, MyCompany">
        <property name="customProperty" value="configuration string"/>
    </object>

    <object id="debugInterceptor" type="Spring.Aop.Advice.DebugAdvice, Spring.Aop">
    </object>

    <object id="person" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">

        <property name="proxyInterfaces" value="MyCompany.MyApp.IPerson"/>

        <property name="target" ref="personTarget"/>

        <property name="interceptorNames">
            <list>
                <value>debugInterceptor</value>
                <value>myCustomInterceptor</value>
            </list>
        </property>

    </object>

Note that the `InterceptorNames` property takes a list of `strings`: the object names of the interceptor or advisors in the current context. Advisors, interceptors, before, after returning and throws advice objects can be used. The ordering of advisors is significant.

The "person" object definition above can be used in place of an `IPerson` implementation, as follows:

    IPerson person = (IPerson) factory.GetObject("person");

Other objects in the same IoC context can express a strongly typed dependency on it, as with an ordinary .NET object:

    <object id="personUser" type="MyCompany.MyApp.PersonUser, MyCompany">
        <property name="person" ref="person"/>
    </object>

The `PersonUser` class in this example would expose a property of type `IPerson`. As far as it's concerned, the AOP proxy can be used transparently in place of a "real" person implementation. However, its type would be a proxy type. It would be possible to cast it to the `IAdvised` interface (discussed below).

It's possible to conceal the distinction between target and proxy using an anonymous inline object, as follows. (for more information on inline objects see .) Only the `ProxyFactoryObject` definition is different; the advice is included only for completeness:

    <object id="myCustomInterceptor" type="MyCompany.MyApp.MyCustomInterceptor, MyCompany">
        <property name="customProperty" value="configuration string"/>
    </object>

    <object id="debugInterceptor" type="Spring.Aop.Advice.DebugAdvice, Spring.Aop">
    </object>

    <object id="person" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">

        <property name="proxyInterfaces" value="MyCompany.MyApp.IPerson"/>

        <property name="target">
          <!-- Instead of using a reference to target, just use an inline object -->
          <object type="MyCompany.MyApp.Person, MyCompany">
            <property name="name" value="Tony"/>
            <property name="age" value="51"/>
          </object>
        </property>

        <property name="interceptorNames">
            <list>
                <value>debugInterceptor</value>
                <value>myCustomInterceptor</value>
            </list>
        </property>

    </object>

This has the advantage that there's only one object of type `Person`: useful if we want to prevent users of the application context obtaining a reference to the un-advised object, or need to avoid any ambiguity with Spring IoC autowiring. There's also arguably an advantage in that the ProxyFactoryObject definition is self-contained. However, there are times when being able to obtain the un-advised target from the factory might actually be an advantage: for example, in certain test scenarios.

### Applying advice on a per-proxy basis.

Let's look at an example of configuring the proxy objects retrieved from `ProxyFactoryObject`.

              <!-- create the object to reference -->
              <object id="RealObjectTarget" type="MyRealObject" singleton="false"/>
              <!-- create the proxied object for everyone to use-->
              <object id="MyObject" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
              <property name="proxyInterfaces" value="MyInterface" />
              <property name="isSingleton" value="false"/>
              <property name="targetName" value="RealObjectTarget" />
              </object>

If you are using a prototype as the target you must set the `TargetName` property with the name/object id of your object and not use the property `Target` with a reference to that object. This will then allow a new proxy to be created around a new prototype target instance.

Consider the above Spring.Net object configuration. Notice that the `IsSingleton` property of the `ProxyFactoryObject` instance is set to false. This means that each proxy object will be unique. Thus, you can configure each proxy object with its' own individual advice(s) using the following syntax

    // Will return un-advised instance of proxy object
    MyInterface myProxyObject1 = (MyInterface)ctx.GetObject("MyObject");

    // myProxyObject1 instance now has an advice attached to it.
    IAdvised advised = (IAdvised)myProxyObject1;
    advised.AddAdvice( new DebugAdvice() );

    // Will return a new, un-advised instance of proxy object
    MyInterface myProxyObject2 = (MyInterface)ctx.GetObject("MyObject");

### Proxying Classes

What if you need to proxy a class, rather than one or more interfaces?

Imagine that in our example above, there was no `IPerson` interface, rather we needed to advise a class called `Person` that didn't implement any business interface. In this case the `ProxyFactoryObject` will proxy all public virtual methods and properties if no interfaces are explicitly specified or if no interfaces are found to be present on the target object. One can configure Spring.NET to force the use of class proxies, rather than interface proxies, by setting the `ProxyTargetType` property on the `ProxyFactoryObject` above to true.

Class proxying works by generating a subclass of the target class at runtime. Spring.NET configures this generated subclass to delegate method calls to the original target: the subclass is used to implement the Decorator pattern, weaving in the advice.

Class proxying should generally be transparent to users. However, there is an important issue to consider: Non-`virtual` methods can't be advised, as they can't be overridden. This may be a limiting factor when using existing code as it has been common practice not to declare methods as virtual by default.

### Concise proxy definitions

Especially when defining transactional proxies, if you do not make use of the transaction namespace, you may end up with many similar proxy definitions. The use of parent and child object definitions, along with inner object definitions, can result in much cleaner and more concise proxy definitions.

First a parent, template, object definition is created for the proxy:

    <object id="txProxyTemplate"  abstract="true"
                type="Spring.Transaction.Interceptor.TransactionProxyFactoryObject, Spring.Data">

            <property name="PlatformTransactionManager" ref="adoTransactionManager"/>
            <property name="TransactionAttributes">
                <name-values>
                    <add key="*" value="PROPAGATION_REQUIRED"/>
                </name-values>
            </property>
        </object>

This will never be instantiated itself, so may actually be incomplete. Then each proxy which needs to be created is just a child object definition, which wraps the target of the proxy as an inner object definition, since the target will never be used on its own anyway.

    <object name="testObjectManager" parent="txProxyTemplate">
            <property name="Target">
                <object type="Spring.Data.TestObjectManager, Spring.Data.Integration.Tests">
                    <property name="TestObjectDao" ref="testObjectDao"/>
                </object>
            </property>
    </object>

It is of course possible to override properties from the parent template, such as in this case, the transaction propagation settings:

    <object name="testObjectManager" parent="txProxyTemplate">
            <property name="Target">
                <object type="Spring.Data.TestObjectManager, Spring.Data.Integration.Tests">
                    <property name="TestObjectDao" ref="testObjectDao"/>
                </object>
            </property>
            <property name="TransactionAttributes">
                <name-values>
                    <add key="Save*" value="PROPAGATION_REQUIRED"/>
                    <add key="Delete*" value="PROPAGATION_REQUIRED"/>
                    <add key="Find*" value="PROPAGATION_REQUIRED,readonly"/>
                </name-values>
            </property>
    </object>

Note that in the example above, we have explicitly marked the parent object definition as abstract by using the abstract attribute, as described previously, so that it may not actually ever be instantiated. Application contexts (but not simple object factories) will by default pre-instantiate all singletons. It is therefore important (at least for singleton object) that if you have a (parent) object definition which you intend to use only as a template, and this definition specifies a class, you must make sure to set the abstract attribute to true, otherwise the application context will actually try to pre-instantiate it.

## Proxying mechanisms

Spring creates AOP proxies built at runtime through the use of the TypeBuilder API.

Two types of proxies can be created, composition based or inheritance based. If the target object implements at least one interface then a composition based proxy will be created, otherwise an inheritance based proxy will be created.

The composition based proxy is implemented by creating a type that implements all the interfaces specified on the target object. The actual class name of this dynamic type is 'GUID' like. A private field holds the target object and the dynamic type implementation will first execute any advice before or after making the target object method call on the target object.

The inheritance based mechanism creates a dynamic type where that inherits from the target type. This lets you downcast to the target type if needed. Please note that in both cases a target method implementation that calls other methods on the target object will not be advised. To force inheritance based proxies you should either set the `ProxyTargetType` to true property of a ProxyFactory or set the XML namespace element `proxy-target-type = true` when using an AOP schema based configuration.

An important alternative approach to inheritance based proxies is disucssed in the next section.

In .NET 2.0 you can define the assembly level attribute, InternalsVisibleTo, to allow access of internal interfaces/classes to specified 'friend' assemblies. If you need to create an AOP proxy on an internal class/interface add the following code, [assembly: InternalsVisibleTo("Spring.Proxy")] and [assembly: InternalsVisibleTo("Spring.DynamicReflection")] to your to AssemblyInfo file.

### InheritanceBasedAopConfigurer

There is an important limitation in the inheritance based proxy as described above, all methods that manipulate the state of the object should be declared as virtual. Otherwise some method invocations get directed to the private 'target' field member and others to the base class. Winform object are an example of case where this approach does not apply. To address this limitation, a new post-processing mechanism was introduced in version 1.2 that creates a proxy type without the private 'target' field. Interception advice is added directly in the method body before invoking the base class method.

To use this new inheritance based proxy described in the note above, declare an instance of the InheritanceBasedAopConfigurer, and IObjectFactoryPostProcessor, in yoru configuraiton file. Here is an example.

    <object type="Spring.Aop.Framework.AutoProxy.InheritanceBasedAopConfigurer, Spring.Aop">
      <property name="ObjectNames">
          <list>
              <value>Form*</value>
              <value>Control*</value>
          </list>
      </property>
      <property name="InterceptorNames">
          <list>
              <value>debugInterceptor</value>
          </list>
      </property>
    </object>

    <object id="debugInterceptor" type="AopPlay.DebugInterceptor, AopPlay"/>

This configuraiton style is similar to the autoproxy by name approach described here and is particuarly appropriate when you want to apply advice to WinForm classes.

## Creating AOP Proxies Programatically with the ProxyFactory

It's easy to create AOP proxies Programatically using Spring.NET. This enables you to use Spring.NET AOP without dependency on Spring.NET IoC.

The following listing shows creation of a proxy for a target object, with one interceptor and one advisor. The interfaces implemented by the target object will automatically be proxied:

    ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);
    factory.AddAdvice(myMethodInterceptor);
    factory.AddAdvisor(myAdvisor);
    IBusinessInterface tb = (IBusinessInterface) factory.GetProxy();

The first step is to construct an object of type `Spring.Aop.Framework.ProxyFactory`. You can create this with a target object, as in the above example, or specify the interfaces to be proxied in an alternate constructor.

You can add interceptors or advisors, and manipulate them for the life of the `ProxyFactory.`

There are also convenience methods on `ProxyFactory` (inherited from `AdvisedSupport`) allowing you to add other advice types such as before and throws advice. `AdvisedSupport` is the superclass of both `ProxyFactory` and `ProxyFactoryObject`.

Integrating AOP proxy creation with the IoC framework is best practice in most applications. We recommend that you externalize configuration from .NET code with AOP, as in general.

## Manipulating Advised Objects

However you create AOP proxies, you can manipulate them using the `Spring.Aop.Framework.IAdvised` interface. Any AOP proxy can be cast to this interface, whatever other interfaces it implements. This interface includes the following methods and properties:

    public interface IAdvised
    {
        IAdvisor[] Advisors {	get; }

        IIntroductionAdvisor[] Introductions { get; }

        void  AddInterceptor(IInterceptor interceptor);

        void  AddInterceptor(int pos, IInterceptor interceptor);

        void  AddAdvisor(IAdvisor advisor);

        void  AddAdvisor(int pos, IAdvisor advisor);

        void  AddIntroduction(IIntroductionAdvisor advisor);

        void  AddIntroduction(int pos, IIntroductionAdvisor advisor);

        int IndexOf(IAdvisor advisor);

        int IndexOf(IIntroductionAdvisor advisor);

        bool RemoveAdvisor(IAdvisor advisor);

        void RemoveAdvisor(int index);

        bool RemoveInterceptor(IInterceptor interceptor);

        bool RemoveIntroduction(IIntroductionAdvisor advisor);

        void RemoveIntroduction(int index);

        void ReplaceIntroduction(int index, IIntroductionAdvisor advisor);

        bool ReplaceAdvisor(IAdvisor a, IAdvisor b);
    }

The `Advisors` property will return an `IAdvisor` for every advisor, interceptor or other advice type that has been added to the factory. If you added an `IAdvisor`, the returned advisor at this index will be the object that you added. If you added an interceptor or other advice type, Spring.NET will have wrapped this in an advisor with a `IPointcut` that always returns `true`. Thus if you added an `IMethodInterceptor`, the advisor returned for this index will be a `DefaultPointcutAdvisor` returning your `IMethodInterceptor` and an `IPointcut` that matches all types and methods.

The `AddAdvisor()` methods can be used to add any `IAdvisor`. Usually this will be the generic `DefaultPointcutAdvisor`, which can be used with any advice or pointcut (but not for introduction).

By default, it's possible to add or remove advisors or interceptors even once a proxy has been created. The only restriction is that it's impossible to add or remove an introduction advisor, as existing proxies from the factory will not show the interface change. (You can obtain a new proxy from the factory to avoid this problem.)

Depending on how you created the proxy, you can usually set a `Frozen` flag, in which case the `IAdvised` `IsFrozen` property will return `true`, and any attempts to modify advice through addition or removal will result in an `AopConfigException`. The ability to freeze the state of an advised object is useful in some cases: For example, to prevent calling code removing a security interceptor.

## Using the "autoproxy" facility

So far we've considered explicit creation of AOP proxies using a `ProxyFactoryObject` or similar factory objects. For applications that would like create many AOP proxies, say across all the classes in a service layer, this approach can lead to a lengthy configuration file. To simplify the creation of many AOP proxies Spring provides "autoproxy" capabilities that will automatically proxy object definitions based on higher level criteria that will group together multiple objects as candidates to be proxied.

This functionality is built on Spring "object post-processor" infrastructure, which enables modification of any object definition as the container loads. Refer to for general information on object post-processors.

In this model, you set up some special object definitions in your XML object definition file configuring the auto proxy infrastructure. This allows you just to declare the targets eligible for autoproxying: you don't need to use `ProxyFactoryObject`.

- Using an autoproxy creator that refers to specific objects in the current context.

- A special case of autoproxy creation that deserves to be considered separately; autoproxy creation driven by source-level attributes.

Autoproxying in general has the advantage of making it impossible for callers or dependencies to obtain an un-advised object. Calling GetObject("MyBusinessObject1") on an ApplicationContext will return an AOP proxy, not the target business object. The "inline object" idiom shown earlier in also offers this benefit.)

### Autoproxy object definitions

The namespace `Spring.Aop.Framework.AutoProxy` provides generic autoproxy infrastructure, should you choose to write your own autoproxy implementations, as well as several out-of-the-box implementations. Two implementations are provided, `ObjectNameAutoProxyCreator` and `DefaultAdvisorAutoProxyCreator`. These are discussed in the following sections.

#### ObjectNameAutoProxyCreator

The `ObjectNameAutoProxyCreator` automatically creates AOP proxies for object with names matching literal values or wildcards. The pattern matching expressions supported are of the form "*name", "name*", and "*name*" and exact name matching, i.e. "name". The following simple classes are used to demonstrate this autoproxy functionality.

    public enum Language
    {
        English = 1,
        Portuguese = 2,
        Italian = 3
    }

    public interface IHelloWorldSpeaker
    {
       void SayHello();
    }

    public class HelloWorldSpeaker : IHelloWorldSpeaker
    {
        private Language language;

        public Language Language
        {
            set { language = value; }
            get { return language; }
        }

        public void SayHello()
        {
            switch (language)
            {
                case Language.English:
                    Console.WriteLine("Hello World!");
                    break;
                case Language.Portuguese:
                    Console.WriteLine("Oi Mundo!");
                    break;
                case Language.Italian:
                    Console.WriteLine("Ciao Mondo!");
                    break;
            }
        }
    }

    public class DebugInterceptor : IMethodInterceptor
    {
        public object Invoke(IMethodInvocation invocation)
        {
            Console.WriteLine("Before: " + invocation.Method.ToString());
            object rval = invocation.Proceed();
            Console.WriteLine("After:  " + invocation.Method.ToString());
            return rval;
        }

    }

The following XML is used to automatically create an AOP proxy and apply a Debug interceptor to object definitions whose names match "English*" and "PortugueseSpeaker".

    <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.ObjectNameAutoProxyCreator, Spring.Aop">
      <property name="ObjectNames">
          <list>
              <value>English*</value>
              <value>PortugeseSpeaker</value>
          </list>
      </property>
      <property name="InterceptorNames">
          <list>
              <value>debugInterceptor</value>
          </list>
      </property>
    </object>

    <object id="debugInterceptor" type="AopPlay.DebugInterceptor, AopPlay"/>

    <object id="EnglishSpeakerOne" type="AopPlay.HelloWorldSpeaker, AopPlay">
      <property name="Language" value="English"/>
    </object>

    <object id="EnglishSpeakerTwo" type="AopPlay.HelloWorldSpeaker, AopPlay">
      <property name="Language" value="English"/>
    </object>

    <object id="PortugeseSpeaker" type="AopPlay.HelloWorldSpeaker, AopPlay">
      <property name="Language" value="Portuguese"/>
    </object>

    <object id="ItalianSpeakerOne" type="AopPlay.HelloWorldSpeaker, AopPlay">
      <property name="Language" value="Italian"/>
    </object>

As with `ProxyFactoryObject`, there is an InterceptorNames property rather than a list of interceptors, to allow correct behavior for prototype advisors. Named "interceptors" can be advisors or any advice type.

The same advice will be applied to all matching objects. Note that if advisors are used (rather than the interceptor in the above example), the pointcuts may apply differently to different objects.

Running the following simple program demonstrates the application of the AOP interceptor.

    IApplicationContext ctx = ContextRegistry.GetContext();
    IDictionary speakerDictionary = ctx.GetObjectsOfType(typeof(IHelloWorldSpeaker));
    foreach (DictionaryEntry entry in speakerDictionary)
    {
        string name = (string)entry.Key;
        IHelloWorldSpeaker worldSpeaker = (IHelloWorldSpeaker)entry.Value;
        Console.Write(name + " says; ");
        worldSpeaker.SayHello();
    }

The output is shown below

    ItalianSpeakerOne says; Ciao Mondo!
    EnglishSpeakerTwo says; Before: Void SayHello()
    Hello World!
    After:  Void SayHello()
    PortugeseSpeaker says; Before: Void SayHello()
    Oi Mundo!
    After:  Void SayHello()
    EnglishSpeakerOne says; Before: Void SayHello()
    Hello World!
    After:  Void SayHello()

#### DefaultAdvisorAutoProxyCreator

A more general and extremely powerful auto proxy creator is `DefaultAdvisorAutoProxyCreator`. This will automatically apply eligible advisors in the current application context, without the need to include specific object names in the autoproxy advisor's object definition. It offers the same merit of consistent configuration and avoidance of duplication as `ObjectNameAutoProxyCreator`.

Using this mechanism involves:

- Specifying a `DefaultAdvisorAutoProxyCreator` object definition

- Specifying any number of Advisors in the same or related contexts. Note that these must be Advisors, not just interceptors or other advices. This is necessary because there must be a pointcut to evaluate, to check the eligibility of each advice to candidate object definitions.

The `DefaultAdvisorAutoProxyCreator` will automatically evaluate the pointcut contained in each advisor, to see what (if any) advice it should apply to each object defined in the application context.

This means that any number of advisors can be applied automatically to each business object. If no pointcut in any of the advisors matches any method in a business object, the object will not be proxied.

The `DefaultAdvisorAutoProxyCreator` is very useful if you want to apply the same advice consistently to many business objects. Once the infrastructure definitions are in place, you can simply add new business objects without including specific proxy configuration. You can also drop in additional aspects very easily--for example, tracing or performance monitoring aspects--with minimal change to configuration.

The following example demonstrates the use of `DefaultAdvisorAutoProxyCreator`. Expanding on the previous example code used to demonstrate `ObjectNameAutoProxyCreator` we will add a new class, `SpeakerDao`, that acts as a Data Access Object to find and store `IHelloWorldSpeaker` objects.

    public interface ISpeakerDao
    {
        IList FindAll();

        IHelloWorldSpeaker Save(IHelloWorldSpeaker speaker);
    }

    public class SpeakerDao : ISpeakerDao
    {
        public System.Collections.IList FindAll()
        {
            Console.WriteLine("Finding speakers...");
    	// just a demo...fake the retrieval.
            Thread.Sleep(10000);
            HelloWorldSpeaker speaker = new HelloWorldSpeaker();
            speaker.Language = Language.Portuguese;

            IList list = new ArrayList();
            list.Add(speaker);
            return list;
        }

        public IHelloWorldSpeaker Save(IHelloWorldSpeaker speaker)
        {
            Console.WriteLine("Saving speaker...");
            // just a demo...not really saving...
            return speaker;
        }

    }

The XML configuration specifies two Advisors, that is, the combination of advice (the behavior to add) and a pointcut (where the behavior should be applied). A

RegularExpressionMethodPointcutAdvisor

is used as a convenience to specify the pointcut as a regular expression that matches methods names. Other pointcuts of your own creation could be used, in which case a

DefaultPointcutAdvisor

would be used to define the Advisor. The object definitions for these advisors, advice, and SpeakerDao object are shown below

    <object id="SpeachAdvisor" type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">

        <property name="advice" ref="debugInterceptor"/>
        <property name="patterns">
            <list>
                <value>.*Say.*</value>
            </list>
        </property>

    </object>

    <object id="AdoAdvisor" type="Spring.Aop.Support.RegularExpressionMethodPointcutAdvisor, Spring.Aop">

        <property name="advice" ref="timingInterceptor"/>
        <property name="patterns">
            <list>
                <value>.*Find.*</value>
            </list>
        </property>

    </object>

    // Advice
    <object id="debugInterceptor" type="AopPlay.DebugInterceptor, AopPlay"/>

    <object id="timingInterceptor" type="AopPlay.TimingInterceptor, AopPlay"/>

    // Speaker DAO Object - has 'FindAll' Method.
    <object id="speakerDao" type="AopPlay.SpeakerDao, AopPlay"/>

    // HelloWorldSpeaker objects as previously listed.

Adding an instance of `DefaultAdvisorAutoProxyCreator` to the configuration file

    <object id="ProxyCreator" type="Spring.Aop.Framework.AutoProxy.DefaultAdvisorAutoProxyCreator, Spring.Aop"/>

will apply the debug interceptor on all objects in the context that have a method that contains the text "Say" and apply the timing interceptor on objects in the context that have a method that contains the text "Find". Running the following code demonstrates this behavior. Note that the "Save" method of SpeakerDao does not have any advice applied to it.

    IApplicationContext ctx = ContextRegistry.GetContext();
    IDictionary speakerDictionary = ctx.GetObjectsOfType(typeof(IHelloWorldSpeaker));
    foreach (DictionaryEntry entry in speakerDictionary)
    {
        string name = (string)entry.Key;
        IHelloWorldSpeaker worldSpeaker = (IHelloWorldSpeaker)entry.Value;
        Console.Write(name + " says; ");
        worldSpeaker.SayHello();
    }
    ISpeakerDao dao = (ISpeakerDao)ctx.GetObject("speakerDao");
    IList speakerList = dao.FindAll();
    IHelloWorldSpeaker speaker = dao.Save(new HelloWorldSpeaker());

This produces the following output

    ItalianSpeakerOne says; Before: Void SayHello()
    Ciao Mondo!
    After:  Void SayHello()
    EnglishSpeakerTwo says; Before: Void SayHello()
    Hello World!
    After:  Void SayHello()
    PortugeseSpeaker says; Before: Void SayHello()
    Oi Mundo!
    After:  Void SayHello()
    EnglishSpeakerOne says; Before: Void SayHello()
    Hello World!
    After:  Void SayHello()
    Finding speakers...
    Elapsed time = 00:00:10.0154745
    Saving speaker...

The DefaultAdvisorAutoProxyCreator offers support for filtering (using a naming convention so that only certain advisors are evaluated, allowing use of multiple, differently configured, AdvisorAutoProxyCreators in the same factory) and ordering. Advisors can implement the `Spring.Core.IOrdered` interface to ensure correct ordering if this is an issue. The default is unordered.

#### PointcutFilteringAutoProxyCreator

An AutoProxyCreator that identified objects to proxy by matching a specified `IPointcut`.

#### TypeNameAutoProxyCreator

An AutoProxyCreator that identifies objects to proxy by matching their `Type.FullName` against a list of patterns.

#### AttributeAutoProxyCreator

An AutoProxyCreator, that identifies objects to be proxied by checking any System.Attribute defined on a given type and that types interfaces.

#### AbstractFilteringAutoProxyCreator

The base class for AutoProxyCreator implementations that mark objects eligible for proxying based on arbitrary criteria.

#### AbstractAutoProxyCreator

This is the superclass of DefaultAdvisorAutoProxyCreator. You can create your own autoproxy creators by subclassing this class, in the unlikely event that advisor definitions offer insufficient customization to the behavior of the framework `DefaultAdvisorAutoProxyCreator`.

### Using attribute-driven auto-proxying

A particularly important type of autoproxying is driven by attributes. The programming model is similar to using Enterprise Services with ServicedComponents.

In this case, you use the `DefaultAdvisorAutoProxyCreator`, in combination with Advisors that understand attributes. The Advisor pointcut is identified by the presence of .NET attribute in the source code and it is configured via the data and/or methods of the attribute. This is a powerful alternative to identifying the advisor pointcut and advice configuration through traditional property configuration, either programmatic or through XML based configuration.

Several of the aspect provided with Spring use attribute driven autoproxying. The most prominent example is Transaction support.

## Using AOP Namespace

The AOP namespace allows you to define an advisor, i.e pointcut + 1 piece of advice, in a more declarative manner. Under the covers the DefaultAdvisorAutoProxyCreator is being used. Here is an example,

    <objects xmlns="http://www.springframework.net"
    		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    		xmlns:aop="http://www.springframework.net/aop">

    	<aop:config>

    		<aop:advisor id="getDescriptionAdvisor" pointcut-ref="getDescriptionCalls" advice-ref="getDescriptionCounter"/>

    	</aop:config>

    	<object id="getDescriptionCalls"
    		type="Spring.Aop.Support.SdkRegularExpressionMethodPointcut, Spring.Aop">
    		<property name="patterns">
    			<list>
    				<value>.*GetDescription.*</value>
    			</list>
    		</property>
    	</object>

    	<object id="getDescriptionCounter" type="Spring.Aop.Framework.CountingBeforeAdvice, Spring.Aop.Tests"/>

    	<object name="testObject" type="Spring.Objects.TestObject, Spring.Core.Tests"/>

    </objects>

In this example, the TestObject, which implements the interface ITestObject, is having AOP advice applied to it. The method GetDescription() is specified as a regular expression pointcut. The aop:config tag and subsequent child tag, aop:advisor, brings together the pointcut with the advice.

In order to have Spring.NET recognise the aop namespace, you need to declare the namespace parser in the main Spring.NET configuration section. For convenience this is shown below. Please refer to the section titled context configuration for more extensive information..

    <configuration>

      <configSections>
        <sectionGroup name="spring">

          <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/>
          <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />

          <section name="parsers" type="Spring.Context.Support.NamespaceParsersSectionHandler, Spring.Core"/>

         </sectionGroup>
      </configSections>

      <spring>

        <parsers>
          <parser type="Spring.Aop.Config.AopNamespaceParser, Spring.Aop" />
        </parsers>

        <context>
          <resource uri="config://spring/objects"/>
        </context>

        <objects xmlns="http://www.springframework.net">
            ...
        </objects>

      </spring>

    </configuration>

## Using TargetSources

Spring.NET offers the concept of a TargetSource, expressed in the `Spring.Aop.ITargetSource` interface. This interface is responsible for returning the "target object" implementing the joinpoint. The `TargetSource` implementation is asked for a target instance each time the AOP proxy handles a method invocation.

Developers using Spring.NET AOP don't normally need to work directly with TargetSources, but this provides a powerful means of supporting pooling, hot swappable and other sophisticated targets. For example, a pooling TargetSource can return a different target instance for each invocation, using a pool to manage instances.

If you do not specify a TargetSource, a default implementation is used that wraps a local object. The same target is returned for each invocation (as you would expect).

Let's look at the standard target sources provided with Spring.NET, and how you can use them.

### Hot swappable target sources

The `org.Spring.NETframework.aop.target.HotSwappableTargetSource` exists to allow the target of an AOP proxy to be switched while allowing callers to keep their references to it.

Changing the target source's target takes effect immediately. The `HotSwappableTargetSource` is thread safe.

You can change the target via the `swap()` method on HotSwappableTargetSource as follows:

    HotSwappableTargetSource swapper =
        (HotSwappableTargetSource) objectFactory.GetObject("swapper");
    object oldTarget = swapper.swap(newTarget);

The XML definitions required look as follows:

    <object id="initialTarget" type="MyCompany.OldTarget, MyCompany">
    </object>

    <object id="swapper"
        type="Spring.Aop.Target.HotSwappableTargetSource, Spring.Aop">
        <constructor-arg><ref local="initialTarget"/></constructor-arg>
    </object>

    <object id="swappable"
        type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop"
    >
        <property name="targetSource">
            <ref local="swapper"/>
        </property>
    </object>

The above `swap()` call changes the target of the swappable object. Clients who hold a reference to that object will be unaware of the change, but will immediately start hitting the new target.

Although this example doesn't add any advice--and it's not necessary to add advice to use a `TargetSource`--of course any `TargetSource` can be used in conjunction with arbitrary advice.

### Pooling target sources

Using a pooling target source provides a programming model in which a pool of identical instances is maintained, with method invocations going to free objects in the pool.

A crucial difference between Spring.NET pooling and pooling in .NET Enterprise Services pooling is that Spring.NET pooling can be applied to any PONO. (Plain old .NET object). As with Spring.NET in general, this service can be applied in a non-invasive way.

Spring.NET provides out-of-the-box support using a pooling implementation based on Jakarta Commons Pool 1.1, which provides a fairly efficient pooling implementation. It's also possible to subclass `Spring.Aop.Target.AbstractPoolingTargetSource` to support any other pooling API.

Sample configuration is shown below:

    <object id="businessObjectTarget" type="MyCompany.MyBusinessObject, MyCompany" singleton="false">
        ... properties omitted
    </object>

    <object id="poolTargetSource" type="Spring.Aop.Target.SimplePoolTargetSource, Spring.Aop">
        <property name="targetObjectName" value="businessObjectTarget"/>
        <property name="maxSize" value="25"/>
    </object>

    <object id="businessObject" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
        <property name="targetSource" ref="poolTargetSource"/>
        <property name="interceptorNames" value="myInterceptor"/>
    </object>

Note that the target object--"businessObjectTarget" in the example--must be a prototype. This allows the `PoolingTargetSource` implementation to create new instances of the target to grow the pool as necessary. See the SDK documentation for `AbstractPoolingTargetSource` and the concrete subclass you wish to use for information about it's properties: maxSize is the most basic, and always guaranteed to be present.

In this case, "myInterceptor" is the name of an interceptor that would need to be defined in the same IoC context. However, it isn't necessary to specify interceptors to use pooling. If you want only pooling, and no other advice, don't set the interceptorNames property at all.

It's possible to configure Spring.NET so as to be able to cast any pooled object to the `Spring.Aop.Target.PoolingConfig` interface, which exposes information about the configuration and current size of the pool through an introduction. You'll need to define an advisor like this:

    <object id="poolConfigAdvisor"
        type="Spring.Object.Factory.Config.MethodInvokingFactoryObject, Spring.Aop">
        <property name="target" ref="poolTargetSource" />
        <property name="targetMethod" value="getPoolingConfigMixin" />
    </object>

This advisor is obtained by calling a convenience method on the `AbstractPoolingTargetSource` class, hence the use of `MethodInvokingFactoryObject`. This advisor's name (`'poolConfigAdvisor'` here) must be in the list of interceptor names in the `ProxyFactoryObject` exposing the pooled object.

The cast will look as follows:

    PoolingConfig conf = (PoolingConfig) objectFactory.GetObject("businessObject");
    Console.WriteLine("Max pool size is " + conf.getMaxSize());

Simpler pooling is available using autoproxying. It's possible to set the TargetSources used by any autoproxy creator.

### Prototype target sources

Setting up a "prototype" target source is similar to a pooling TargetSource. In this case, a new instance of the target will be created on every method invocation. Although the cost of creating a new object may not be high, the cost of wiring up the new object (satisfying its IoC dependencies) may be more expensive. Thus you shouldn't use this approach without very good reason.

To do this, you could modify the `poolTargetSource` definition shown above as follows. (the name of the definition has also been changed, for clarity.)

    <object id="prototypeTargetSource"
            type="Spring.Aop.Target.PrototypeTargetSource, Spring.Aop">
        <property name="targetObjectName" value="businessObject" />
    </object>

There is only one property: the name of the target object. Inheritance is used in the TargetSource implementations to ensure consistent naming. As with the pooling target source, the target object must be a prototype object definition, the singleton property of the target should be set to false.

### ThreadLocal target sources

ThreadLocal target sources are useful if you need an object to be created for each incoming request (per thread that is). The concept of a ThreadLocal provides a facility to transparently store resource alongside a thread. Setting up a ThreadLocalTargetSource is pretty much the same as was explained for the other types of target source:

    <object id="threadlocalTargetSource"
            type="Spring.Aop.Target.ThreadLocalTargetSource, Spring.Aop">
        <property name="targetObjectName" value="businessObject" />
    </object>

## Defining new Advice types

Spring.NET AOP is designed to be extensible. While the interception implementation strategy is presently used internally, it is possible to support arbitrary advice types in addition to interception around, before, throws, and after returning advice, which are supported out of the box.

The `Spring.Aop.Framework.Adapter` package is an SPI (Service Provider Interface) package allowing support for new custom advice types to be added without changing the core framework. The only constraint on a custom Advice type is that it must implement the `AopAlliance.Aop.IAdvice` tag interface.

Please refer to the `Spring.Aop.Framework.Adapter` namespace documentation for further information.

## Further reading and resources

The Spring.NET team recommends the excellent AspectJ in Action by Ramnivas Laddad (Manning, 2003) for an introduction to AOP.

If you are interested in more advanced capabilities of Spring.NET AOP, take a look at the test suite as it illustrates advanced features not discussed in this document.