Simple AOP: call interception with DynamicProxy

February 14, 2009 at 2:37 AMAndre Loker

Aspect oriented programming (AOP) allows us to keep implement different concerns in isolation. In this article series I’ll describe ways to make use of AOP without much hassle. After the introduction to AOP in the first article I’ll show how we can use Castle DynamicProxy to intercept method calls for the injection of advice code.

Introduction

If you’re reading this, you are probably interested in AOP and want to know how you can practise separation of concerns in you .NET application. There are quite some AOP frameworks available for .NET, so you might just grab the one that best fits your need. Below you’ll find an (incomplete!) overview of existing AOP frameworks for .NET

Examples for frameworks using compile time weaving/IL level manipulation:

Those frameworks weave the aspect code into compiled assemblies by modifying the IL code.

Examples for frameworks using proxy-based runtime weaving

The common technique behind those framework is this: for each class that needs to have advices applied to it the framework creates a subclass at runtime using the runtime code generation facilities of .NET. Each virtual call or interface method implementation is overridden. Those overridden methods can then redirect the call to the advices. As a result those frameworks normally only support a very small join point model, limited to the calls of virtual methods or interface methods. However, in many practical cases, this limitation is not that much of an issue.

Choose your destiny

Here we already have six frameworks to choose from. The question is: which one should I use or should I even use a different approach? I haven’t used all of those frameworks, so I can’t go into a detailed analysis of their commonalities and differences. Nevertheless, here are some general thoughts:

  1. If a specific concern is suitable for static weaving you probably want to go that way. As mentioned in the first article, compile time weaving has several benefits, especially allowing a much richer join point model and slightly less overhead.
  2. If you use Spring.NET or S2Container as your IoC container, using the respective AOP facility is probably the recommended way.
  3. If you need dynamic weaving and use the Castle stack read on, that’s what the rest of this article is about!

Castle facilities

Interestingly enough, Castle once had an AOP facility itself. It has been discontinued a while ago because apparently it wasn’t used much. It’s not that people find AOP as a concept useless, but it seems that a fully blown AOP framework is not required in many cases. Instead, people find a different facility to be sufficient, namely DynamicProxy2.

DynamicProxy2 (DP2) is a library that generates proxy types at runtime. DP2 supports different proxy strategies. In the case of AOP, two strategies are the most important:

  1. Create a class proxy: DP2 derives a proxy class from a given type.

class proxy

  1. Create an interface proxy with a target: instead of deriving from the target type, this strategy creates an implementation of one (or multiple) of the interfaces that the target type implements. This strategy resembles the classic Proxy pattern, because the instance created by DP2 replaces the target object.

interface proxy

Interceptors

Just creating new types at runtime is rather useless if that’s all. Of course, there is more. When you use DP2 to create the proxy instances you can provide one or more interceptors. An interceptor is an object implementing IInterceptor, which looks like this:

   1: public interface IInterceptor
   2: {
   3:     void Intercept(IInvocation invocation);
   4: }

Each virtual or interface method that the DP2 proxy generator overrides or implements respectively will call the Intercept() method of the interceptors you pass to the generator method. The IInvocation instance passed to the interceptor contains information about the method being intercepted:

   1: public interface IInvocation
   2: {
   3:     // Methods
   4:     object GetArgumentValue(int index);
   5:     MethodInfo GetConcreteMethod();
   6:     MethodInfo GetConcreteMethodInvocationTarget();
   7:     void Proceed();
   8:     void SetArgumentValue(int index, object value);
   9:  
  10:     // Properties
  11:     object[] Arguments { get; }
  12:     Type[] GenericArguments { get; }
  13:     object InvocationTarget { get; }
  14:     MethodInfo Method { get; }
  15:     MethodInfo MethodInvocationTarget { get; }
  16:     object Proxy { get; }
  17:     object ReturnValue { get; set; }
  18:     Type TargetType { get; }
  19: }

One of the most important members is Proceed() which will call the next IInterceptor for the current proxy or – if the current interceptor is the last one – it will invoke the “real” method.

DP2 in practice

Let’s put all this theoretic mumbo-jumbo into practice, shall we?

First, here’s our ultra complex domain model:

   1: // A service interface...
   2: public interface IService {
   3:   void DoSomething();
   4: }
   5:  
   6: // ... and its implementation
   7: public class Service : IService {
   8:   public void DoSomething() {
   9:     Console.Out.WriteLine("Service.DoSomething()");
  10:   }
  11: }

Nothing fancy here. Here’s our application code:

   1: public class Program {
   2:   public static void Main() {
   3:     IService service = CreateService();
   4:     service.DoSomething();
   5:   }
   6:  
   7:   private static IService CreateService() {
   8:     return new Service();
   9:   }
  10: }

If we run this – surprise – this is the result (the last line is “Press any key” in German)

image

Now we introduce DynamicProxy2. First off, add a reference to Castle.Core.dll and Castle.DynamicProxy2.dll.  Now we can write our first interceptor:

   1: public class LogInterceptor : IInterceptor {
   2:   public void Intercept(IInvocation invocation) {
   3:     Console.WriteLine("Intercepting {0}", invocation.Method.Name);
   4:   }
   5: }

Not bad so far. Finally, we need to inject the interceptor into the target. To do this, modify CreateService like this:

   1: private static IService CreateService() {
   2:   var dp = new ProxyGenerator();
   3:   var target = new Service();
   4:   var interceptor = new LogInterceptor();
   5:   return dp.CreateInterfaceProxyWithTarget<IService>(target, interceptor);
   6: } 

Now run the code again:

image

Wait, where’s “Service.DoSomething()”? We forgot one thing: if we don’t call Proceed() on the IInvocation object in Intercept(), the original method (or the next interceptor) won’t be called, so adjust the LogInterceptor like this:

   1: public void Intercept(IInvocation invocation) {
   2:   Console.WriteLine("Intercepting {0}", invocation.Method.Name);
   3:   // invoke next interceptor/intercepted method
   4:   invocation.Proceed();
   5: }

And voilá:

image

You see, calling Proceed() is necessary to have the intercepted method executed. This has several positive side effects:

  1. We can intentionally decide to block the call to the intercepted methods, for example for security reasons
  2. In the interceptor we can provide that has to be called before and after the execution of the intercepted method (“around advice” anyone?)
  3. We can “fork”, i.e. we can invoke the intercepted method multiple times

If we have more than one interceptor, calling Proceed() will only invoke the intercepted method if the current interceptor is the last one. Calling Proceed() in interceptors that are earlier in the chain will instead invoke the next interceptor. Here’s a collaboration diagram of a proxy with two interceptors:

image

Personally I think that having Proceed() do the right thing transparently is a wise choice.

The link to AOP

You’ve probably already noticed where this is going. We can use DP2 and the interceptors to implement our advices. Out advices are in fact implementations of IInterceptor and the ProxyGenerator acts as the weaver. Here’s another (not really useful) advice using IInterceptor:

   1: public class ExceptionAdvice : IInterceptor {
   2:  
   3:   public bool EatAll { get; set; }
   4:  
   5:   public void Intercept(IInvocation invocation) {
   6:     try {
   7:       invocation.Proceed();
   8:     } catch (Exception e) {
   9:       Console.WriteLine("{0} caught: {1}", e.GetType().Name, e.Message);
  10:       if (!EatAll) {
  11:         throw;
  12:       }
  13:     }
  14:   }
  15: }

Let’s add it into our case:

   1: private static IService CreateService() {
   2:   var dp = new ProxyGenerator();
   3:   var target = new Service();
   4:   var interceptor = new LogInterceptor();
   5:   // swallow all exceptions
   6:   var exceptionAdvice = new ExceptionAdvice {EatAll = true};
   7:   return dp.CreateInterfaceProxyWithTarget<IService>(target, interceptor, exceptionAdvice);
   8: }

If Service.SomeMethod now throws an exception we see this:

image

I’m sure you can come up with a bunch of more realistic concerns that could be implemented using IInterceptors.

Loose ends

Intercepting join points is probably one of the technically most difficult parts of an AOP framework. Luckily Castle DynamicProxy is a feasible tool for this. Let’s see how this intermediate solution compares to a “real” AOP framework:

  • All methods of the target are intercepted. Sometimes you want only a subset of the methods based e.g. on an attribute or the name of the method. Therefore the Intercept method needs to further filter invocations. It would be cool if we could somehow more declaratively define our pointcuts.
  • We have to explicitly generate the proxies with the interceptors. We’d like to have this done automatically. Luckily Castle Windsor, the IoC container of the Castle stack, has this feature built in, so we can make the interceptors part of the component model.
  • We can only intercept virtual methods or interface methods. Well, there’s not much we can do about it, this is an inherent problem of the proxy based weaving approach. If you need a richer join point model, have a look at frameworks supporting compile time weaving.
  • We currently only support around advices. That’s not too bad, given that it is the “mother” of all advices we can “derive” all kind of advice types. For example, you can provide a set of abstract advice classes from which the concrete advices are derived. Just derive from the correct advice type and implement the abstract method (decide for yourself whether this approach is useful for you):
   1: public abstract class AroundAdvice : IInterceptor {
   2:   void IInterceptor.Intercept(IInvocation invocation) {
   3:     Around(invocation);
   4:   }
   5:  
   6:   protected abstract void Around(IInvocation invocation);
   7: }
   8:  
   9: public abstract class BeforeAdvice : IInterceptor {
  10:   void IInterceptor.Intercept(IInvocation invocation) {
  11:     Before(invocation);
  12:     invocation.Proceed();
  13:   }
  14:  
  15:   protected abstract void Before(IInvocation invocation);
  16: }
  17:  
  18: public abstract class AfterAdvice : IInterceptor {
  19:   void IInterceptor.Intercept(IInvocation invocation) {
  20:     try {
  21:       invocation.Proceed();
  22:     } finally {
  23:       After(invocation);
  24:     }
  25:   }
  26:  
  27:   protected abstract void After(IInvocation invocation);
  28: }
  29:  
  30: public abstract class AfterReturningAdvice : IInterceptor {
  31:   void IInterceptor.Intercept(IInvocation invocation) {
  32:     invocation.Proceed();
  33:     AfterReturning(invocation);
  34:   }
  35:  
  36:   protected abstract void AfterReturning(IInvocation invocation);
  37: }
  38:  
  39: public abstract class AfterThrowingAdvice : IInterceptor {
  40:   void IInterceptor.Intercept(IInvocation invocation) {
  41:     try {
  42:       invocation.Proceed();
  43:     } catch (Exception e) {
  44:       AfterThrowing(invocation, e);
  45:     }
  46:   }
  47:  
  48:   protected abstract void AfterThrowing(IInvocation invocation, Exception e);
  49: }

Preview

The next part of the series will cover integration of interceptors into Castle Windsor. Have fun!

Attached you'll find the source code for this article.

DynamicProxyEx1.zip (243.14 kb)

Other articles in this series:

Posted in: Castle | Design | Snippets

Tags: , , , , , ,

Subtle design: inheritance vs roles

February 10, 2009 at 11:04 AMAndre Loker

Let’s say you’re supposed to design a staff administration. Part of the domain model are managers and employees. Whenever you talk to your client you hear sentences such as “some of our employees are managers of a given department” or similar. Therefore, you might be tempted to model employees and managers as an “is-a” relationship, that is, you use inheritance.

isa

Let us evaluate this (really simple!) model critically. What implications does a design like this have, assuming that we are going to implement this model in a OO language like C#?

1. First of all, it implies that everyone is either an employee or a manager throughout his or her life. Although we can principally model “dynamic inheritance” in e.g. ERDs, in a language such as C# we can’t change the type of an instance all of a sudden. So, if you create a new employee, you’d have to decide whether it is in fact an employee or a manager and create an instance of the according type. As a consequence, an employee can’t be promoted to a manager and a manager can’t be degraded to a simple employee.

2. An employee can’t manage more than one department. Because one employee can’t be “multiple managers at once” (although some might which to when looking at their schedule *g*), there’s no way to let some employee manager multiple departments. Of course, in this simple model you could change the cardinality of the Manager <-> Departmennt relationship. But as soon as you for example want to assign a bonus payment to managers dependent on the manager itself and the department, simply associating multiple departments to a single manager won’t do the trick anymore.

By now you should have realized that modelling the employee-manager relationship as an “is-a” is rather inflexible. We can improve the design if we reconsider the meaning “some of our employees are managers of a given department”. What this actually means is: “some of our employees are in the role of being a manager of a given department”. Thus, being a manager is a role played by a player, ie. the employee. In general this can be modelled like:

role1As you see the player can play multiple roles, each role is played by only one player. We can easily attach or detach roles as needed without changing the type of the player. Putting the role-player relationship into our case leads to:

emproleThis design is much more flexible: employees can start as “normal” employees, can be promoted or degraded and can manage as many departments at once as required.

Identification and countability

When do you model a relationship as inheritance and when as a role-player relationship? To help you make this decision R. J. Wieringa (see references below) suggests to determine how the different entities are counted and how they are identified. If we count managers, do we count in fact employees? If so, each manager should be identified the same way as employees, e.g. by an employee number. In that case managers and employees can be modelled using inheritance. On the other hand, if managers are counted and identified differently from employees (e.g. using a management contract number) we should apply the role-player relationship.

Another example given by Mr Wieringa is the relationship between persons and passengers on a flight. Modelling passengers as a subtype of persons is probably not optimal because it would imply that a person can only be a passenger once. Passengers are most likely not counted as persons. They are probably identified by a ticket number not by e.g. a social security number.

Conclusion

Be critical if you model “obvious” is-a relationships. Do you really have a case of specialization or is the “subtype” only a role that is played by the general type?

References

Once again the concepts presented in this article are based on Design Methods for Reactive Systems by R.J. Wieringa (Amazon) (And no, I don’t get any commission for recommending this book).

Posted in: Design | Patterns

Tags: ,

Subtle design: snapshot cardinalities

February 9, 2009 at 3:02 PMAndre Loker

So your designing some application, let’s say for a library. Being the DDD guy that you are, you talk to a clerk at the library and she tells you that the system under development should save the fact that a book is lent out by a specific reader. So you choose to model that fact like this:

book You present this diagram to the library manager and he’s slightly confused: “What’s that? Our books are lent out by hundreds or thousands of people. Your design supports only one reader!”

You answer: “No, no. This model only says that a book is lent out by a single reader at a given time.

What happened here is that the library manager and you had a different idea of what portion of time the UML model represented. For you, the cardinalities shown in the diagram represented so called Snapshot Cardinalities, ie. cardinalities that occur at a single point in time. E.g. at any given moment, a book is lent by not more than one reader. The manager looked from a different perspective and interpreted the cardinalities as being historic. Throughout the lifetime of a book it is lent out by many readers, therefore his confusion.

The moral of the story

  • don’t assume that everyone looking at an UML diagram has the same idea of the semantics of numbers (or arrows for that matter).
  • be aware that we can have snapshot cardinalities as well as historic cardinalities. Most of the time you’ll use snapshot cardinalities because that’s what you’ll probably use in your code later on. Nevertheless, make that clear to the people with which you’re talking about the diagram
  • don’t mix different types of cardinalities, or be very explicit if you do so

For the interested reader I recommend R.J. Wieringa, Design Methods for Reactive Systems (Amazon)

Posted in: Patterns | Design

Tags: ,