Search code examples
c#.netcastlecastle-dynamicproxy

How to access custom method attributes from ProxyGenerationHook in Castle.DynamicProxy


I'm implementing Interceptor mechanism in .NET with Castle.DynamicProxy (Castle.Core 4.4.0). I'm following this tutorial for selecting which method to intercept: https://kozmic.net/2009/01/17/castle-dynamic-proxy-tutorial-part-iii-selecting-which-methods-to/

It was given an example in this article about "selecting which methods to intercept":

public class FreezableProxyGenerationHook:IProxyGenerationHook
{
    public bool ShouldInterceptMethod(Type type, MethodInfo memberInfo)
    {
        return !memberInfo.Name.StartsWith("get_", StringComparison.Ordinal);
    }
    //implementing other methods... 
}

According to this article, I implemented the ShouldInterceptMethod like below but i can not access the method's custom attributes.

public class ProductServiceProxyGenerationHook : IProxyGenerationHook
{
    public void MethodsInspected()
    {
    }
    public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
    {
    }

    public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
    {
        //return methodInfo.CustomAttributes.Any(a => a.GetType() == typeof(UseInterceptorAttribute));
        return methodInfo.CustomAttributes.Count() > 0;
    }
}

This is the method that i want to intercept:

[UseInterceptor]
public Product AOP_Get(string serialNumber)
{
    throw new NotImplementedException();      
}

This is my custom attribute:

[System.AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
sealed class UseInterceptorAttribute : Attribute
{
    public UseInterceptorAttribute()
    {
    }
}

When ShouldInterceptMethod invoked for AOP_Get method, there aren't any custom attributes on local variable methodInfo. As a result ShouldInterceptMethod returns false. But when i check from the AOP_Get method body, i can access custom attribute like below:

How can i access custom attributes in ShouldInterceptMethod method?


Solution

  • I solved the problem using UseInterceptorAttribute in the interface methods. Because the interceptor is enabling for interface:

    //autofac
    var proxyGenerationOptions = new ProxyGenerationOptions(new ProductServiceProxyGenerationHook());
    
    builder.RegisterType<ProductService>()
                    .As<IProductService>()
                    .EnableInterfaceInterceptors(proxyGenerationOptions)
                    .InterceptedBy(typeof(LoggingInterceptor));
    

    The solution:

    public interface IProductService
    {
        Product Get(string productNumber, string serialNumber);
    
        bool Create(string productNumber, string serialNumber);
    
        [UseInterceptor]
        Product AOP_Get(string productNumber, string serialNumber);
    
    }
    
    public class ProductService : IProductService
    { 
        public Product AOP_Get(string productNumber, string serialNumber)
        {
            var m = GetType().GetMethod("AOP_Get");
            return null;
        }
    
        public bool Create(string productNumber, string serialNumber)
        {
            return true;
        }
    
        public Product Get(string productNumber, string serialNumber)
        {
            return new Product
            {
                Id = 5,
                ProductNumber = "testPN",
                SerialNumber = "testSN"
            };
        }
    }
    
        public class ProductServiceProxyGenerationHook : IProxyGenerationHook
        {
            public void MethodsInspected()
            {
            }
    
            public void NonProxyableMemberNotification(Type type, MemberInfo memberInfo)
            {
            }
    
            public bool ShouldInterceptMethod(Type type, MethodInfo methodInfo)
            {
                return methodInfo
                    .CustomAttributes
                    .Any(a => a.AttributeType == typeof(UseInterceptorAttribute));
            }
        }
    }