Part 1 and part 2 of this series were devoted to Unity, and part 3 introduced interception. Let’s examine Unity’s interception mechanism in more details.
Let’s look at the GetContainer method once again:
1 public IUnityContainer GetContainer()
2 {
3 IUnityContainer container = new UnityContainer();
4 container.AddNewExtension<Interception>();
5
6 //define how to intercept
7 container.Configure<Interception>()
8 .SetDefaultInterceptorFor<AccountingService>(new VirtualMethodInterceptor());
9
10 //create policy
11 container.Configure<Interception>()
12 .AddPolicy("SecurityPolicy")
13 .AddMatchingRule(new TypeMatchingRule(typeof(AccountingService)))
14 .AddCallHandler<SecurityCallHandler>();
15
16 return container;
17 }
From this code, you can see a few concepts being introduced.
The first is the configuration of an interceptor, which defines how interception is to be made for the specified class. In this case, we are using the VirtualMethodInterceptor which creates a new class, on the fly, which derives from the AccountingService and overrides anything virtual as place holders for executing the policies (more on policies later).
The current interceptors are:
- VirtualMethodInterceptor, which can intercept virtual calls by deriving a a class from the intercepted class.
- InterfaceInterceptor, which can intercept any call on a given a interface, by creating a class that implements the specified interface and decorates the concrete type.
- TransparentProxyInterceptor, which can intercept anything deriving from MarshalByRefObject or an interface and reuses the .net technology for remoting. Out of the three, this is the slowest interceptor but also the one that is the most flexible.
The other part of configuring is the creation of a policy. A policy is basically something that has a name (RuleDrivenPolicy), knows how to identify things it needs to intercept (IMatchingRule) and calls handlers (ICallHandler).
Out of the box, Unity comes with many matching rules but no call handlers. If you are using Enteprise Libary’s PIAB, you will find that PIAB implements may call handlers for invoking the security, logging, exception management…
The following code will get you on your way to creating your own call handlers:
1 public class SampleCallHandler : ICallHandler
2 {
3 #region ICallHandler Members
4
5 public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
6 {
7 //before next CallHandler or Target Method
8 IMethodReturn result = getNext.Invoke().Invoke(input, getNext);
9 //after previous CallHandler or Target Method
10
11 return result;
12 }
13
14 public int Order
15 {
16 get { return 0; }
17 set { }
18 }
19
20 #endregion
21 }
Note that there is always a AttributeDrivenPolicy present in the container, which uses attributes for matching rules and call handlers. All you have to do is create attributes that derive from HandlerAttribute and off you go.
In part 2, we saw the we could also configure the container through xml configuration files. The same is true for interception and GetContainer would look like this:
1 public IUnityContainer GetContainer()
2 {
3 IUnityContainer container = new UnityContainer();
4
5 UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
6 section.Containers.Default.Configure(container);
7
8 return container;
9 }
The exact same syntax as for configuring Unity, isn’t that great ! The backing XML though is another thing, here is an example:
1 <?xml version="1.0" encoding="utf-8" ?>
2 <configuration>
3 <configSections>
4 <section
5 name="unity"
6 type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
7 </configSections>
8 <unity>
9 <containers>
10 <container>
11 <types>
12 <type type="Demo1.AccountingService,TestAssembly"/>
13 </types>
14 <extensions>
15 <add type="Microsoft.Practices.Unity.InterceptionExtension.Interception, Microsoft.Practices.Unity.Interception" />
16 </extensions>
17 <extensionConfig>
18 <add name="interception" type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationElement, Microsoft.Practices.Unity.Interception.Configuration">
19 <interceptors>
20 <interceptor
21 type="transparentProxy">
22 <default
23 type="Demo1.AccountingService,TestAssembly"/>
24 </interceptor>
25 </interceptors>
26 <policies>
27 <policy name="SecurityPolicy">
28 <matchingRules>
29 <matchingRule
30 name="matchingRule"
31 type="AlwaysMatchingRule"/>
32 </matchingRules>
33 <callHandlers>
34 <callHandler
35 name="callHandler"
36 type="SampleCallHandler"/>
37 </callHandlers>
38 </policy>
39 </policies>
40 </add>
41 </extensionConfig>
42 </container>
43 </containers>
44 </unity>
45 </configuration>
Now how’s that for XML !!!
We hope that these posts will reassure you and help you integrate Unity into your software. Unity is quite powerful and we have only touched the surface. Feel free to write to use to get more information.