DarioSantarelli.Blog(this);

Archive for September, 2012

Unity Interception Extension

Posted by dariosantarelli on September 30, 2012


Starting from Enterprise Library 5.0, Unity supports interception mechanisms which captures the call to an object at invocation time and provides the full implementation of the object through lightweight code generation (ILEmit). It’s something very similar to the aspect-oriented programming (AOP) approach.

However, Unity is NOT an AOP framework implementation for the following reasons:

  • It uses interception to enable only preprocessing behaviors and post-processing behaviors.
  • It does not insert code into methods, although it can create derived classes containing policy pipelines.
  • It does not provide interception for class constructors.

Instance Interception VS Type Interception

With instance interception, when the application resolves the object through the container,

  1. The Unity interception container obtains a new or an existing instance of the object and creates a proxy.
  2. Then it creates the handler pipeline and connects it to the target object before returning a reference to the proxy.
  3. The client then calls methods and sets properties on the proxy as though it were the target object.

Interface interception

With type interception , the container uses a derived class instead of a proxy (it  resembles AOP techniques). Type interception avoids the possible performance penalties of using a proxy object by dynamically deriving a new class from the original class, and inserting calls to the behaviors that make up the pipeline. When the application resolves the required type through the Unity container,

  1. the Unity interception container extension creates the new derived type and passes it, rather than the resolved type, back to the caller.
  2. Because the type passed to the caller derives from the original class, it can be used in the same way as the original class.
  3. The caller simply calls the object, and the derived class will pass the call through the behaviors in the pipeline just as is done when using instance interception.

Type Interception

However, there are some limitations with this approach. It can only be used to intercept public and protected virtual methods, and cannot be used with existing object instances. In general, type interception is most suited to scenarios where you create objects especially to support interception and allow for the flexibility and decoupling provided by policy injection, or when you have mappings in your container for base classes that expose virtual methods.

Interceptors and Behaviors

Unity uses an Interceptor class to specify how interception happens, and an InterceptionBehavior class to describe what to do when an object is intercepted. There are three built-in interceptors in Unity:

  • VirtualMethodInterceptor: a type based interceptor that works by generating a new class on the fly that derives from the target class. It uses dynamic code generation to create a derived class that gets instantiated instead of the original, intercepted class and to hook up the call handlers. Interception only happens on virtual methods. You must set up interception at object creation time and cannot intercept an existing object.
  • InterfaceInterceptor:  an instance interceptor that works by generating a proxy class on the fly for a single interface. It can proxy only one interface on the object. It uses dynamic code generation to create the proxy class. Proxy supports casting to all the interfaces or types of the target object. It only intercepts methods on a single interface. It cannot cast a proxy back to target object’s class or to other interfaces on the target object.
  • TransparentProxyInterceptor: an instance interceptor that uses remoting proxies to do the interception. When the type to intercept is a MarshalByRefObject or when only methods from the type’s implemented interfaces need to be intercepted. The object must either implement an interface or inherit from System.MarshalByRefObject. If the marshal by reference object is not a base class, you can only proxy interface methods. TheTransparentProxy process is much slower than a regular method call.

Interception is based on one or a pipeline of behaviors that describe what to do when an object is intercepted. You can create your own custom behaviors by implementing the IInterceptionBehavior interface. The interception behaviors are added to a pipeline and are called for each invocation of that pipeline, as shown below.

Here an example of interception behavior which intercepts a call to a method and logs some useful info if the call throws an exception internally:

public class ExceptionLoggerInterceptionBehavior : IInterceptionBehavior
{
  private readonly ILogger _logger;
 

  public ExceptionLogInterceptionBehavior(ILogger logger)
  {
    _logger = logger;
  }
 
  public IEnumerable<Type> GetRequiredInterfaces() return Type.EmptyTypes; }

  public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)    
  {
      IMethodReturn result = getNext()(input, getNext);

      if (result.Exception != null)
      {
        _logger.Log(string.Format(“Exception occurred in {0}.\nParameters: {1}\nException: {2},
                               input.MethodBase,
                               string.Join(“,”, input.Inputs.Cast<object>()),
                               result.Exception));
      }
      return result;
  }
 
  public bool WillExecute
  {
    get { return true; }
  }
}

In detail, you must provide an implementation of the two IInterceptionBehavior interface methods, Invoke() and GetRequiredInterfaces(), and set the WillExecute property.

  • The WillExecute property indicate if the behavior perform any operation when invoked. This is used to optimize interception. If the behaviors won’t actually do anything (for example, PIAB where no policies match) then the interception mechanism can be skipped completely.
  • The GetRequiredInterfaces method returns the interfaces required by the behavior for the intercepted objects. The Invoke method execute the behavior processing.
  • The Invoke method has two parameters: input and getNext. The input parameter rapresents the current call to the original method, the getNext parameter is a delegate to execute to get the next delegate in the behavior chain.

Now let’s see an example of usage.  The following code executes a statement that makes my IService implementation raise an ArgumentNullException. This exception will be logged thanks to the ExceptionLoggerInterceptionBehavior registered for my IService interface.

new UnityContainer()
    .AddNewExtension<Interception>()
    .RegisterType<ILogger, ConsoleLogger>()
    .RegisterType<IService, Service>(new Interceptor<InterfaceInterceptor>(),
                                     new InterceptionBehavior<ExceptionLoggingInterceptionBehavior>())
.Resolve<IService>()
.Process(null); // It throws ArgumentNullException!!!

If we open the Console output window we’ll find something like this…

Exception occurred in MyNamespace.Response Process(MyNamespace.Request).
Parameters:
Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: request
at MyNamespace.Service.Process(Request request) in …
at DynamicModule.ns.Wrapped_IService_1cccb54f8a8b4109a353b589ea96c30e.<Process_DelegateImplementation>__0(IMethodInvocation inputs, GetNextInterceptionBehaviorDelegate getNext)

A first chance exception of type ‘System.ArgumentNullException’ occurred in Unity_ILEmit_InterfaceProxies

Posted in .NET Framework, C#, Microsoft Technology, Programming | Tagged: , , | 1 Comment »

Unity container and the Decorator Pattern

Posted by dariosantarelli on September 12, 2012


In these days I’m using Unity as IoC and DI container in a project. One of the “must-have” features of a modern container is the ability to be configured at runtime, preferably with a  fluent mapping registration interface. Moreover, one of the expected features is the support for decorator or chain object pattern configurations with intuitive code. A simple scenario could be something like this:

public interface IService {}

public class Service : IService {}

public class ServiceDecorator : IService
{
  protected IService DecoratedService { get; private set; }

  public ServiceDecorator(IService service)
  {
    DecoratedService = service;
  }
}

The intent is straightforward and quite common: registering the relationship between the Service and the ServiceDecorator class, so when someone asks for an IService, he gets a Service instance wrapped in a ServiceDecorator instance. Let’s have a look at the most used solutions.

 

Solution 1: Using an InjectionConstructor

Well, configuring the Unity container to support a decorator in the old-fashioned way requires some not so much readable code. In fact, making this work seems a kind of magic.

[TestMethod]
public void UnityContainer_Should_Resolve_The_ServiceDecorator_With_InjectionConstructor()
{
  var container = newUnityContainer();
  container.RegisterType<IService, Service>(“Service”);
  container.RegisterType<IService,ServiceDecorator>(
                new InjectionConstructor(new ResolvedParameter(typeof(IService), “Service”)));
 
  var service = container.Resolve<IService>();
  Assert.IsInstanceOfType(service, typeof(ServiceDecorator));

}

I think the code above is not optimal, because it uses magic strings.  It also has a dangerous disadvantage: changes to the ServiceDecorator constructors will generate runtime instead of compile time errors.

 

Solution 2: Using an InjectionFactory

This is a substantial improvement of the previous solution. It allows to specify a factory function which can use the injected container to explicitly resolve eventual dependencies to decorated/decorator constructors.

[TestMethod]
public void UnityContainer_Should_Resolve_The_ServiceDecorator_With_InjectionFactory()
{
 var container = new UnityContainer();
 Func<IUnityContainer, object> factoryFunc = c => new ServiceDecorator(new Service(
       // Here you can use the container to resolve further dependencies…
 ));

 container.RegisterType<IService>(new InjectionFactory(factoryFunc));

 var service = container.Resolve<IService>();
 Assert.IsInstanceOfType(service, typeof(ServiceDecorator));
}

The downside is that code still needs updating every time a new constructor parameter is added to Service or ServiceDecorator class. But now we have three noticeable advantages:

  • code is much easier to understand
  • only a single registration into the container is required
  • changes to the constructors will generate compile time instead of runtime errors.

 

Solution 3: Using a custom Unity Container Extension

You can use a container extension like this DecoratorContainerExtension in order to use the same convention available for example in the Castle Windsor container:

[TestMethod]
public void UnityContainer_Should_Resolve_The_ServiceDecorator_With_DecoratorContainerExtension()
{
  var container = new UnityContainer();
  container.AddNewExtension<DecoratorContainerExtension>();
  container.RegisterType<IService, ServiceDecorator>();
  container.RegisterType<IService, Service>(); 
 
  var service = container.Resolve<IService>();
  Assert.IsInstanceOfType(service, typeof(ServiceDecorator));
}

This is absolutely my favourite solution.  It’s less code, and most importantly it describes the intent in a better way, because it’s focused on the developer’s object model and not the on the Unity’s one.

Posted in .NET Framework, C#, Microsoft Technology, Programming | Tagged: , , | Leave a Comment »