How to use DefaultInterceptor

Oct 24, 2010 at 8:51 AM

Hi, I want to know the correct usage of DefaultInterceptor.

The document tells me that a DefaultInterceptor will be applied any time that type is resolved, regardless of the name used to resolve it.

So, I tried the following code, and got no default interception for the resulting instance's method.

container.RegisterType<IMyClass, MyClass>( // where, MyClass implements IMyClass's method Print().
    new DefaultInterceptor(new InterfaceInterceptor()),
    new InterceptionBehavior(new MyBehavior()));
container.RegisterType<IMyClass, MyClass>("myInterceptor1");
container.Resolve<IMyClass>("myInterceptor1").Print(); 

It works fine if I resove it without name.  Am I missing something, or is this the expected behavior?

Thanks.

Oct 25, 2010 at 1:41 AM
Edited Oct 25, 2010 at 4:44 AM

The registration should not specify the class which implements the type.  Here's the correct registration:

container.RegisterType<IMyClass>( 
    new DefaultInterceptor(new InterfaceInterceptor()),
    new InterceptionBehavior(new MyBehavior()));
container.RegisterType<IMyClass, MyClass>("myInterceptor1");
container.Resolve<IMyClass>("myInterceptor1").Print(); 

Here's the link to the sample code from the documentation:

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

Oct 25, 2010 at 7:58 AM

Thank you for the reply.  Actually, I've tried that already, and it did not work, at least on my machine.

It looks like DefaultInterceptor works only if it appears in the registration where the builder for the object is registered.

That is the reason I placed DefaultInterceptor within the mapping registration; Otherwise I cannot make DefaultInterceptor work at all.

But that is very strange and if it is true, I suspect that there is no use of DefaultInterceptor.

I am pasting here the all-in-one complete sample code I used.

using System;
using System.Collections.Generic;
using Microsoft.Practices.Unity;  // version=2.0.414.0
using Microsoft.Practices.Unity.InterceptionExtension;  // version=2.0.414.0

namespace DefaultInterceptorSample
{
    class Program
    {
        static void Main(string[] args)
        {
            IUnityContainer container = new UnityContainer();
            container.AddNewExtension<Interception>();
            container.RegisterType<IMyClass>(
                new DefaultInterceptor(new InterfaceInterceptor()),
                //new DefaultInterceptor<VirtualMethodInterceptor>(),
                new InterceptionBehavior(new MyBehavior()));
            container.RegisterType<IMyClass, MyClass>("myInterceptor1");
            container.Resolve<IMyClass>("myInterceptor1").Print();
            Console.ReadLine();
        }
    }

    public interface IMyClass { void Print(); }

    public class MyClass : IMyClass
    {
        public virtual void Print() { Console.WriteLine("MyClass:Print"); }
    }

    class MyBehavior : IInterceptionBehavior
    {
        public IEnumerable<Type> GetRequiredInterfaces() { return Type.EmptyTypes; }

        public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
            Console.WriteLine("MyBehavior Invoked for Method: {0}", input.MethodBase.Name);
            return getNext()(input, getNext);
        }

        public bool WillExecute { get { return true; } }
    }
}

Oct 25, 2010 at 8:20 AM

Sorry I didn't notice before.  You should also use the DefaultInterceptionBehavior rather than the InterceptionBehavior.  So this is actually how the registration should be:

container.RegisterType<IMyClass>( 
    new DefaultInterceptor(new InterfaceInterceptor()),
    new DefaultInterceptionBehavior(new MyBehavior()));

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

Oct 25, 2010 at 8:59 AM

Oh, thank you, Sarah.

That is the point I missed out!  It's all clear now.