Configuration Files for Interception
Unity 3 treats interception like any extension you add to Unity. As with any extension in Unity 3, the Unity interception mechanism can be configured through either the API or through a Unity configuration section.
Note: Unity provides partial backward compatibility for implementing interception through a container. Earlier versions used a container extension named InterceptionExtension, which resides in the assembly named Microsoft.Practices.Unity.Interception.dll. To configure interception, you specify this extension in the
This topic contains the following sections to describe the interception configuration file:
- Using the Configuration File to Enable Interception
- Standard Interception Aliases
- Enabling Interception of a Type
- Configuring Policy Injection Policies
- Legacy Interception Configuration
- Interception Configuration Schema Elements
- Registering Interception at Run Time
Using the Configuration File to Enable Interception
Interception is not part of the default Unity configuration schema. Before you can configure interception you must add the correct
The following extract from a configuration file adds the interception extension, InterceptionConfigurationExtension, by using the <sectionExtension>element.
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
</unity>
Loading the interception section extension supplies a set of Standard Interception Aliases and additional configuration elements.
Loading the section extension only enables the interception configuration to be given in the configuration file. Interception itself will not work unless you also load the interception container extension in your Unity container instance. This can also be done in the configuration file, as shown in the following example.
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
<container>
<extension type="Interception" />
</container>
</unity>
You do not need to explicitly alias the interception container extension’s type or add a
Standard Interception Aliases
The following table contains the list of predefined type aliases provided by the Unity interception extension. All of these types are in the Microsoft.Practices.Unity.Interception.dll assembly and the Microsoft.Practices.Unity.InterceptionExtension namespace.
|
Alias
|
Description
| | --- | --- | |
Interception
|
The interception container extension.
| |
IInterceptionBehavior
|
Interface for interception behaviors.
| |
PolicyInjectionBehavior
|
Behavior implementing policy injection.
| |
Policy Injection Types
|
Policy injection types.
| |
ImatchingRule
|
The matching rule interface.
| |
IcallHandler
|
The policy injection call handler interface.
| |
Policy Injection Matching Rules
|
Policy injection matching rules.
| |
AssemblyMatchingRule
|
Match based on being in a particular assembly.
| |
CustomAttributeMatchingRule
|
Match based on having a given attribute.
| |
MemberNameMatchingRule
|
Match based on member name.
| |
ParameterTypeMatchingRule
|
Match based on parameter types.
| |
PropertyMatchingRule
|
Match based on a property name.
| |
TagAttributeMatchingRule
|
Match based on having the Tag attribute.
| |
TypeMatchingRule
|
Match based on type.
| |
Interceptor Types
|
Interceptor type.
| |
VirtualMethodInterceptor
|
Virtual method type interceptor.
| |
InterfaceInterceptor
|
Interface interceptor.
| |
TransparentProxyInterceptor
|
Transparent proxy interceptor.
|
Enabling Interception on a Type
To turn on interception for a type in the container, you specify the interceptor and behaviors using the following child elements of the
The following example turns on interception using the transparent proxy interceptor and performs policy injection.
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
<container>
<extension type="Interception" />
<register type="MyType">
<!-- Other children, like constructor or property -->
<interceptor type="TransparentProxyInterceptor" />
<policyInjection />
</register>
</container>
</unity>
After loading this configuration, any objects of type MyType will be intercepted by using the transparent proxy interceptor and they will have the policy injection behavior applied to them.
Configuring Policy Injection Policies
Policy injection polices can also be configured through the Unity configuration section. This section describes how to perform the configuration along with several options you can use when defining policies.
Policies are defined on a per-container basis inside an
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
<container>
<extension type="Interception" />
<interception>
<policy name="addDataAccessTypes">
<matchingRule name="DataLayerMatch" type="NamespaceMatchingRule">
<constructor>
<param name="namespaceName" value="MyApp.DataAccess" />
</constructor>
</matchingRule>
<callHandler name="LogHandler" type="LoggingCallHandler" />
<callHandler name="SecurityHandler"
type="DatabaseSecurityCheckHandler" />
</policy>
<policy name="webMethods">
<matchingRule name="MatchWebRequestMethods" />
<callHandler name="LogWebMethodHandler" type="LoggingCallHandler" />
</policy>
</interception>
<register type="IMatchingRule" name="MatchWebRequestMethods"
mapTo="MemberNameMatchingRule">
<constructor>
<param name="nameToMatch" value="Begin*Request" />
</constructor>
</register>
</container>
</unity>
This example demonstrates the two most common approaches for defining matching rules and call handlers in a configuration file. The first approach, the inline style, declares the type and injection members directly within the policy definition. This is what was used in the first matching rule declaration, as shown in the following extract from the previous example.
...
<matchingRule name="DataLayerMatch" type="NamespaceMatchingRule">
<constructor>
<param name="namespaceName" value="MyApp.DataAccess" />
</constructor>
</matchingRule>
...
This approach is designed to work much like a
The same design applies to the
The second most common approach is to use a named reference, as in the following example with the MatchWebRequestMethods named reference.
...
<matchingRule name="MatchWebRequestMethods" />
...
<register type="IMatchingRule" name="MatchWebRequestMethods"
mapTo="MemberNameMatchingRule">
<constructor>
<param name="nameToMatch" value="Begin*Request" />
</constructor>
</register>
...
In this approach, a type of matching rule is not specified. Instead, a name is provided. At configuration time, the container will attempt to resolve an IMatchingRule with the name MatchWebRequestMethods that you specified. The result is that the container will look for a registration for the type ICallHandler with the name MatchWebRequestMethods. That registration is defined a few lines lower in the previous example file, which works because the order of definition in the file does not matter. The same design applies to the
The name is always required by the configuration system. However, when using an inline style registration, the name is ignored in the container.
The approach you choose to use is a matter of personal preference. The following are factors to consider when choosing an approach to use for policies, matching rules, and call handlers in your configuration file:
- If your policies are fairly small and initialization of the matching rules and call handlers is straightforward, the inline style will be the simplest approach. Everything related to your policies is then in one place.
- If you want to reuse a call handler definition or matching rule across policies, a named reference will facilitate this approach. Using a named reference lets you define the configuration for the call handler or matching rule in a single place and simply reference it from the policies. Choosing the name to describe what the matching rule or call handler’s purpose is makes it easier to track them; for example, MatchWebRequestMethods is clearly for matching methods that do Web requests.
- If you have a large number of policies or many matching rules and call handlers, using named references will facilitate your work. Using the inline style can quickly bloat your policy definitions, making it hard to tell what the policies are and which ones are grouped together.
For more information on registering interception at run time, see Registering Interception.
For more information on registering policies, matchingRules, and callHandlers at run time see Registering Policy Injection Components.
Legacy Interception Configuration
In earlier versions of Unity, enabling interception on a type was done using a separate element entirely. Unity 3 supports this approach as well, in order to allow some reuse of other configuration files. The syntax is not identical, so you will still need to copy and update your configuration file; you cannot use an older Unity configuration file directly. For new development, configuring interception through the
The
<container>
<extension type="Interception" />
<interceptors>
<interceptor type="VirtualMethodInterceptor">
<default type="wrappableVirtual"/>
</interceptor>
<interceptor type="TransparentProxyInterceptor">
<key type="wrappable"/>
</interceptor>
<interceptor type="TransparentProxyInterceptor">
<key type="wrappable" name="name"/>
</interceptor>
</interceptors>
</container>
The
When defining interception through the
For more information on backward compatibility, see Reusing Configuration Files Based on a Previous Schema.
For more information about Unity 1.2 interception, see Using Interception with Unity on MSDN.