Part 1 – Basic of IoC unity container
Part 2 – Basic of resolving dependencies and configure objects.
Part 3 – AOP with Policy Injection Application Block
Part 4 – Custom Handler to use with Policy Injection Application Block
Part 5 – Combine policy Injection Application Block with Unity

In last post I showed how Policy Injection Application Block is now only a tiny wrapper around Unity. So Unity is the enterprise library section that does both AOP and Dependency Injection, this make me a little bit confused :) so I decided to forget about PIAB, just to avoid confusion.

To use AOP with unity without PIAB one of the possible solution is using custom attributes, suppose you write an handler called MyLogHandler, you can just create this attribute.

public class MyLogHandlerAttribute : HandlerAttribute { public override ICallHandler CreateHandler(IUnityContainer container) { return new MyLogHandler(); } }

This one is a particular attribute because it inherit from HandlerAttribute and it needs only to override the CreateHandler method and returns an instance of the handler you want to use. You can apply this attribute to every class or method you want to intercept, if you apply it to a class every method will be intercepted, if you apply it to a single method you will intercept only that method. Here is an example.

[MyLogHandler] interface ILogger { void Log(String message); }

This is not enough to make interception happens, Unity should be instructed that you want the ILogger interface to be intercepted and you must also specify the type of interception.

container.Configure<Interception>().SetDefaultInterceptorFor<ILogger>(new TransparentProxyInterceptor());

You can call SetDefaultInterceptorFor or simply SetInterceptorFor; the first one tells unity container to apply interception every time that a specific type is resolved: when the user calls Resolve<T> or when the type is resolved for some dependency. In the example , this means that when you resolve TestB class, since is has a dependency to ILogger, the Ilogger object that will get resolved will be intercepted. (this is the configuration section for the TestB object)

image

When unity resolve the object named OtherTest it resolves also the dependency to the ILogger interface and creates the SuperLogger, but since I asked to set a default interceptor for the ILogger interface it gets intercepted and wrapped.

image

If you change the code and call SetInterceptorFor instead of SetDefaultInterceptorFor, the situation is different.

image

As you can verify the logger variable contains a transparent proxy because it gets resolved directly, the Logger property of the TestB object is not intercepted because it is resolved for a dependency. Keep in mind this distinction because it is one of the most important in the unity interception structure.

I do not like the code+attributes approach to AOP, because if I need to intercept some other methods I need to modify code and recompile, in a AOP world I want to use only configuration files to specify everything, let’s see how to do it. First of all I set up some alias to make the configuration more readable

<typeAliases> <typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" /> <typeAlias alias="transparentProxy" type="Microsoft.Practices.Unity.InterceptionExtension.TransparentProxyInterceptor, Microsoft.Practices.Unity.Interception" /> <typeAlias alias="typeMatchingRule" type="Microsoft.Practices.Unity.InterceptionExtension.TypeMatchingRule, Microsoft.Practices.Unity.Interception"/>

These aliases permits me to use shorter name in the config. Here is the first part of the config

image

Container configuration has an extension node that permits to add extensions, then you add the corresponding extensionConfig to configure specific extension you’ve added. For interceptors you add a series of <interceptor> node. Each interceptor node must have a type attribute that specify the type of interceptor to use, then you must add a series of <key> or <default> nodes to specify the types to intercept. Each <key> elements will call the SetInterceptorFor, each <default> element calls a SetDefaultConfigurationFor.

Now that interception is configured you need to specify types or methods that should be intercepted, this is done with the Policy element. Each policy element is composed by a series of matching rules that are used to identify methods to be intercepted and a list of handlers to use, here is an example.

image

Unity gives you some basic matching rules, in this example I’ve used a typeMatchingRule (look to the aliases section to verify the exact type). This class permits you to specify a Name of a class that will be intercepted. To specify the name of the class in code you must pass a string to the constructor of the matching rule, in configuration file you can obtain the same result with an <injection> node.

The resulting config file is really verbose, and I must admit that is not so readable, compare it with code configuration

container.Configure<Interception>() .SetDefaultInterceptorFor<ILogger>(new TransparentProxyInterceptor()) .AddPolicy("LogMethod") .AddMatchingRule(new TypeMatchingRule("ILogger")) .AddCallHandler(typeof(MyLogHandler));

Configuration API for Unity permits you to use a simple fluent syntax to configure interception, this kind of configuration is more readable, more manteniable and less error prone. To set interception I needs only five lines, the XML file is really longer an more complex. If you want to use interception in your project, you could configure everything in code and accept to recompile when the configuration change or you can use dynamic compilation to configure container at runtime using code files.

Code for the example can be found here.

alk.

Tags:

10 Responses to “Unity and AOP in enterprise library”

  1. Vincent-Philippe Lauzon
    April 14th, 2009 at 4:11 pm

    Hi,

    I am looking at the sample code you’ve provided. I’m looking for samples (since I didn’t find complete documentation) on how to integration policies inside unity configuration.

    I noticed you did that in “UnityConfiguration.xml” but commented it out. You then go and do the integration using the API.

    What I’m looking for is a way to encapsulate the policies in the Unity configuration so we can simply instantiate the unity container and resolve an instance without “configuring” in code (e.g. .AddPolicy).

    Do you know how to do that? Reading Unity documentation, it seems to be possible but I couldn’t find a sample doing it.

    Thanks in advance!

  2. Sorry for the sample, I used the same file for both the configurations and I commented in and out some parts, this makes the overall sample not so clear.
    If you go into this subversion repository
    http://nablasoft.googlecode.co.....ious/Unity
    you can find an updated version of the sample where I created two configuration file, one to configure interception in code, the other to configure interception only with configuration file. I hope this sample will be clearer.

    Hope to have time to make a better sample with different configurations and more comments.

    Alk.

  3. I think I got the latest version of the code; however, when I run the SimpleWithAOP method at the line that reads

    ITest wrapped = Microsoft.Practices.EnterpriseLibrary.PolicyInjection.PolicyInjection.Wrap(test1);

    I get the following error:
    [Edited by alkampfer]

    Any help would be greatly appreciated.

    Thanks in advance.

  4. Dear tphelps, thanks a lot for pointing out those errors. I edited your comment because it contains the full stack trace and is really long.

    I’ve updated the code and now everything should work. The problem was originated by the fact that, for some configuration, entlib requires yoru ICallHandler to have a constructor that accepts a NameValueCollection parameter, now I inserted those constructor, and a default one (that is needed for some of the example). I’ve also corrected configuration file, because now the MyLogHandler has more than one constructor.

    Moreover the example is a little bit messy, I’ve tried to clean a little, but is a long time I do not work anymore with unity, (I ususally use castle, I’ve used unity in a project already started with unity).

    Hope everything is now ok.

    Alk.

  5. That did it.

    Thanks very much for all your great work on this!

  6. The link you provide to download the code sample comes up as a 404… Can you please provide that sample code once more?

  7. For some strange reason IIS stopped to serve the .7z file :) now I fixed the problem, Try download again the sample and sorry for the inconvenience.

    alk.

Trackbacks/Pingbacks

  1. DotNetShoutout
  2. Arjan`s World » LINKBLOG for January 31, 2009
  3. Cross Site Scripting » Blog Archive » Unity and Aop in Enterprise Library