How to use interception through app.config

Apr 12, 2011 at 9:43 AM
When I use interception feature in Unity, I come up against some problem.

I wanna add a attribute on method to track invoking, like below:

public interface ICalc
{
    [Trace]
    int Add(int oprandA, int oprandB);

    [Trace]
    int Divide(int dividend, int divisor);
}


public class TraceAttribute:HandlerAttribute
{
     public override ICallHandler CreateHandler(IUnityContainer container)
     {
         return new TraceHandler();
     }
}
IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<ICalc, Calc>().Configure<Interception>().SetInterceptorFor<ICalc>(new InterfaceInterceptor());
 
 
 
 
Now, I wanna use the attribute by app.config, not hard code in program:
 
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
  </configSections>

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <aliases>
      <!-- Lifetime manager types -->
      <add alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
      <!-- Custom object types -->
      <add alias="ICalc" type="CallHandlerInterception.ICalc, CallHandlerInterception" />
      <add alias="Calc" type="CallHandlerInterception.Calc, CallHandlerInterception" />
    </aliases>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>
    <containers>
      <container name="ContainerOne">
        <extension type="Interception" />
        <register type="ICalc" mapTo="Calc">
          <interceptor type="InterfaceInterceptor" />
        </register>
      </container>
    </containers>
  </unity>
</configuration>
 
IUnityContainer container = new UnityContainer();
But...It's noneffective.

 

Apr 12, 2011 at 10:18 AM

  In a word, How can I transfer these code to app.config?

IUnityContainer container = new UnityContainer();
container.AddNewExtension<Interception>();
container.RegisterType<ICalc, Calc>().Configure<Interception>().SetInterceptorFor<ICalc>(new InterfaceInterceptor());
So I can use HandlerAttribute just through these code:
IUnityContainer container = new UnityContainer();
Apr 13, 2011 at 12:23 AM

You would need to configure call handler(s) and matching rule(s).  You can refer to this topic from the documentation.

A sample config for your case would be:

<interception>
      <policy name="TracePolicy">
        <matchingRule name="TraceMatch" type="NamespaceMatchingRule">
          <constructor>
            <param name="namespaceName" value="MyApp" />
          </constructor>
        </matchingRule>
        <callHandler name="TraceHandler" type="MyApp.TraceHandler, MyApp" />
      </policy>
</interception>

assuming you declared the corresponding <assembly> and <namespace> elements for the Microsoft.Unity.InterceptionExtension.NamespaceMatchingRule and your class methods to intercept and your TraceHandler class reside in the MyApp namespace.

Hope this helps.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 13, 2011 at 1:33 AM

Thank you very much !

 Configuring it through MATCHING RULE(S)  is attractive, but I will lose advantage of marking Attribute on method.

So, is there any way to use HandlerAttribute without MATCHING RULE(S)?

Apr 13, 2011 at 1:46 AM
Edited Apr 13, 2011 at 1:49 AM

Unfortunately, that isn't how it works.  There's no way to configure handlers in the config and get them to run without specifying any matching rule.  You may need  to resort to implementing a custom behavior rather than a custom call handler.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 13, 2011 at 2:43 AM
AvanadeSupport wrote:

Unfortunately, that isn't how it works.  There's no way to configure handlers in the config and get them to run without specifying any matching rule.  You may need  to resort to implementing a custom behavior rather than a custom call handler.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com


Thank you !

Apr 14, 2011 at 4:02 AM

I'm sorry, Sarah, but you're incorrect. It is completely possible to get interception hooked up through configuration and use call handler attributes without a matching rule.

The issue the O.P. is having is that he set up an interceptor, but he didn't set any behaviors. Using the old configuration API, he avoided this because it automatically adds the policy injection behavior. The configuration does not do this, so it needs to be done explicitly. Luckily, this is pretty simple:

        <register type="ICalc" mapTo="Calc">
          <interceptor type="InterfaceInterceptor" />
          <policyInjection /> <!-- New piece is here -->
        </register>

Do that and the call handler attributes should start to work.

 

Apr 14, 2011 at 4:48 AM

Yes Chris but my understanding was that znfsky wanted to remove the attribute decoration in the methods and make it work through configuration.  Sorry for the confusion znfsky if Chris Tavares' solution would do the trick for you.

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 14, 2011 at 12:12 PM
ctavares wrote:

I'm sorry, Sarah, but you're incorrect. It is completely possible to get interception hooked up through configuration and use call handler attributes without a matching rule.

The issue the O.P. is having is that he set up an interceptor, but he didn't set any behaviors. Using the old configuration API, he avoided this because it automatically adds the policy injection behavior. The configuration does not do this, so it needs to be done explicitly. Luckily, this is pretty simple:

 

        <register type="ICalc" mapTo="Calc">
          <interceptor type="InterfaceInterceptor" />
          <policyInjection /> <!-- New piece is here -->
        </register>

 

Do that and the call handler attributes should start to work.

 


That's what I'm looking for !Thank you very much! All because of old API hide details.

And Sarah, I must thanks for your answer,too.