Search code examples
c#aopautofacinterceptorcastle-dynamicproxy

Autofac Intercept Target Method


I'm using Autofac.Extras.DynamicProxy2 to perform some method interception on a service implementation.

The service has quite a few methods and I only want to target a few.

Is there a better practice besides than checking for invocation target name against an approved string dictionary of methods I want to intercept?

   public void Intercept(IInvocation invocation)
    {
        invocation.Proceed();
        if (ContinueIntercept(invocation))
        {
            // Do intercept work
        }
    }

    private bool ContinueIntercept(IInvocation invocation)
    {            
        // Logic to compare invocation.MethodInvocationTarget.Name 
    }

It really doesn't add all that much over head, but it still feels like a poor way to do it. Especially since adding this to a specific service implementation means it will intercept all of the method calls of the base class common implementation. It wouldn't be as bad if it only intercepted the derived class.

I see that Castle.DynamicProxy2 has ways to specify invocation target, but I don't see how to wire that up with autofac.


Solution

  • You can use a IProxyGenerationHook to specify on which method the ProxyBuilder should generate a proxy.

    public class FooProxyGenerationHook : IProxyGenerationHook
    {
        public void MethodsInspected()
        { }
    
        public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
        { }
    
        public Boolean ShouldInterceptMethod(Type type, MethodInfo methodInfo)
        {
            if (type == typeof(Foo) && methodInfo.Name == "Do")
            {
                return true;
            }
            return false;
        }
    }
    

    Then, you can register it this way :

        ProxyGenerator generator = new ProxyGenerator();
        FooProxyGenerationHook hook = new FooProxyGenerationHook();
        IFoo foo = generator.CreateClassProxyWithTarget<Foo>(new Foo(), new ProxyGenerationOptions(hook), new FooInterceptor());
    

    In order to avoid calling the IProxyGenerationHook for each proxy, you should have only one instance of hook.

    With DynamicProxy2, you can use this code :

        FooProxyGenerationHook hook = new FooProxyGenerationHook();
    
        ContainerBuilder builder = new ContainerBuilder();
        builder.RegisterType<FooInterceptor>().AsSelf();
        builder.RegisterType<Foo>().As<IFoo>()
                .EnableClassInterceptors(new ProxyGenerationOptions(hook))
                .InterceptedBy(typeof(FooInterceptor));