Interception callHandler does not work

Apr 22, 2014 at 12:06 PM
Im trying to use Interception with Microsoft Unity. Somenthing does not work. The application starts and I do not receive any error. But interception does not work... Here the code:

I've configured Interception in web.config:
<types>
   <type type="en.MFS.IFacade.IFacadeMFS, en.MFS.IFacade"
         mapTo="en.MFS.Facade.FacadeMFS, en.MFS.Facade">
       <interceptor type="TransparentProxyInterceptor" />
       <policyInjection />
   </type>
</types>

<extension type="Interception" />
<interception>
    <policy name="LoggerPolicy">
        <matchingRule name="LoggerMatchingRule" type="CustomAttributeMatchingRule">
            <constructor>
                <param name="attributeType" type="System.Type">
                    <value value="en.MFS.LoggerInterception.LoggerAttribute, en.MFS.LoggerInterception"
                           typeConverter="en.MFS.LoggerInterception.GetTypeConverter, en.MFS.LoggerInterception"/>
                </param>
                <param name="inherited" value="true" />
            </constructor>
        </matchingRule>
        <callHandler name="LoggerHandler"
              type="en.MFS.LoggerInterception.LoggerHandler, en.MFS.LoggerInterception" >
            <property name="Order" value="1" />
        </callHandler>
    </policy>
</interception>
Here my Handler:
public class LoggerHandler : BaseHandler
{
    public override IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
    {
        //Here I have a breakpoint

        return getNext().Invoke(input, getNext);
    }
}
BaseHandler is an abstract class that implement ICallHandler:
public abstract class BaseHandler : ICallHandler
{
    public abstract IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext);

    private int _order;
    public int Order
    {
        get
        {
            return _order;
        }
        set
        {
            _order = value;
        }
    }
}
And here my attribute:
public class LoggerAttribute : HandlerAttribute //Attribute
    {
        public int X { get; set; }
        public LoggerAttribute(int x )
        {
            X = x;
        }

        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
        {
            return new LoggerHandler() { Order = 1 };
        }
    }
I think i do not miss anything. Can anyone tell me why it does not work?

Thanx
Apr 22, 2014 at 1:54 PM
How are you using the LoggerAttribute HandlerAttribute? Is the intent to apply the attribute to the applicable class/method? If so, then you don't need to configure an interception policy -- just apply the attribute and configure policyInjection. Here's a sample console application:
    public interface IFacadeMFS
    {
        void Do();
    }

    [Logger(1)]
    public class FacadeMFS : IFacadeMFS
    {
        public void Do()
        {
            Console.WriteLine("Do");
        }
    }

    public class LoggerHandler : BaseHandler
    {
        public override IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
        {
            Console.WriteLine("Start Calling method " + input.MethodBase.Name);
            var methodReturn = getNext().Invoke(input, getNext);
            Console.WriteLine("Done  Calling method " + input.MethodBase.Name);
            return methodReturn;
        }
    }

    public abstract class BaseHandler : ICallHandler
    {
        public abstract IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext);

        private int _order;
        public int Order
        {
            get
            {
                return _order;
            }
            set
            {
                _order = value;
            }
        }
    }

    public class LoggerAttribute : HandlerAttribute //Attribute
    {
        public int X { get; set; }
        public LoggerAttribute(int x)
        {
            X = x;
        }

        public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
        {
            return new LoggerHandler() { Order = 1 };
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer container = new UnityContainer();
            container.LoadConfiguration();

            var facade = container.Resolve<IFacadeMFS>();
            facade.Do();
        }
    }

And the configuration:
<?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">

    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>

    <container>

      <extension type="Interception"/>

      <register type="UnityCallhandlerConfig.IFacadeMFS, UnityCallhandlerConfig"
                mapTo="UnityCallhandlerConfig.FacadeMFS, UnityCallhandlerConfig">
        <interceptor type="TransparentProxyInterceptor" />
        <policyInjection />
      </register>

    </container>

  </unity>

</configuration>

If you don't want to use a HandlerAttribute then you would need to configure an appropriate policy with matching rules.


~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Marked as answer by randylevy on 4/28/2014 at 12:03 AM
Apr 22, 2014 at 3:04 PM
Hi Randy.... Thanx!! Really.... Finally it works... Now I understand when configure the policy... and honestly something else in my code over what i posted was wrong (for example i did not resolve the Facade via Unity... but just the BLL :o )

Your example now works perfectly also in my code.... I hoped I could go on on my own, but when I did other changes the code have not worked anymore :(

Here my new code....

Here my attribute + converter:
public class LoggerAttribute : Attribute //HandlerAttribute 
    {
        public int X { get; set; }
        public LoggerAttribute(int x )
        {
            X = x;
        }

        //public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
        //{
        //    return new LoggerHandler() { Order = 1 };
        //}
    }

    public class GetTypeConverter : TypeConverter
    {
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            object o = Type.GetType(value.ToString());
            return o;
        }

    }
And here the web config:
<interception>
                <policy name="LoggerPolicy">
                  <matchingRule name="LoggerMatchingRule" type="CustomAttributeMatchingRule">
                    <constructor>
                      <param name="attributeType" type="System.Type, mscorlib">
                        <value value="en.Avis.MFS.LoggerInterception.LoggerAttribute, en.Avis.MFS.LoggerInterception"
                               typeConverter="en.Avis.MFS.LoggerInterception.GetTypeConverter, en.Avis.MFS.LoggerInterception"/>
                      </param>
                      <param name="inherited" value="true" />
                    </constructor>
                  </matchingRule>
                  <callHandler name="LoggerHandler"
                               type="en.Avis.MFS.LoggerInterception.LoggerHandler, en.Avis.MFS.LoggerInterception" >
                    <property name="Order" value="1" />
                  </callHandler>
                </policy>
              </interception>
Other thing are exactly the same you posted in your answer before....

In this case, nothing works anymore :(
Can you help me plz?
Apr 23, 2014 at 2:25 PM
CustomAttributeMatchingRule applies to the member and not to the class so the method would need to be attributed:
    public class FacadeMFS : IFacadeMFS
    {
        [Logger(1)]
        public void Do()
        {
            Console.WriteLine("Do");
        }
    }

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Marked as answer by randylevy on 4/28/2014 at 12:03 AM
Apr 23, 2014 at 3:24 PM
Ohh... that's perfect... now it works...

thank you!