【问题标题】:How to access custom method attributes from ProxyGenerationHook in Castle.DynamicProxy如何从 Castle.DynamicProxy 中的 ProxyGenerationHook 访问自定义方法属性
【发布时间】:2021-03-13 15:42:58
【问题描述】:

我正在使用 Castle.DynamicProxy (Castle.Core 4.4.0) 在 .NET 中实现 Interceptor 机制。我正在按照本教程选择要拦截的方法:https://kozmic.net/2009/01/17/castle-dynamic-proxy-tutorial-part-iii-selecting-which-methods-to/

本文中给出了一个关于“选择拦截哪些方法”的例子:

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

根据这篇文章,我实现了ShouldInterceptMethod,如下所示,但我无法访问该方法的自定义属性。

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;
    }
}

这是我要拦截的方法:

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

这是我的自定义属性:

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

当为AOP_Get 方法调用ShouldInterceptMethod 时,局部变量methodInfo 上没有任何自定义属性。结果ShouldInterceptMethod 返回false。但是当我从AOP_Get 方法体中检查时,我可以访问自定义属性,如下所示:

如何在ShouldInterceptMethod 方法中访问自定义属性?

【问题讨论】:

  • 你能上传一个最小的例子到 github,这样我就可以摆弄它了吗?
  • @Simon:我将最小示例上传到 GitHub:link
  • 这个solution 是可用的,但我们仍在拦截所有方法。

标签: c# .net castle castle-dynamicproxy


【解决方案1】:

我在 interface 方法中使用UseInterceptorAttribute 解决了这个问题。因为拦截器正在为接口启用:

//autofac
var proxyGenerationOptions = new ProxyGenerationOptions(new ProductServiceProxyGenerationHook());

builder.RegisterType<ProductService>()
                .As<IProductService>()
                .EnableInterfaceInterceptors(proxyGenerationOptions)
                .InterceptedBy(typeof(LoggingInterceptor));

解决办法:

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));
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多