简介LinFu.DynamicProxy动态代理,及Attribute的构造过程

这里写自定义目录标题

这2天,基于项目可维护性的考虑,要实现一套类似于Java Feign的类库,可以快速并且优雅的声明和调用API,当然,Feign都是接口声明,不考虑做接口实现,因此采用LinFu.DynamicProxy作为动态代理,来拦截所有Feign接口方法的调用。
LinFu.DynamicProxy介绍,可以参考这里,至于为啥不用Castle DynamicProxy,因为Castle依赖太多,基于简单考虑,就用LinFu吧。
关于LinFu.DynamicProxy 和 Castle DynamicProxy这2个库的动态代理使用,我写了2个Demo扔在某hub上了:
LinFu.DynamicProx的示例参考
Castle DynamicProxy的示例参考

-----这里是分割线,下面是特性说明-----
OK,了解Feign的同学都知道,有多少个api,就需要定义多少个Feign方法,每个方法都要特性声明,比如GetMapping、PostMapping等。
在DotNet里,可以通过Type.GetCustomAttributes,获取类上的所有特性声明。
那么,有没有类似Attribute.GetAllType这样的方法,来获取所有声明了某个特性的类呢?
很遗憾,查阅了一些资料,没有这样的方法,只能枚举所有的Type,去一个个调用Type.GetCustomAttributes,类似于:

foreach (Type type in customType.Assembly.GetTypes())
{
    if (type.GetCustomAttributes(typeof(XxxAttribute), false).Length > 0)
    {
        yield return type;
    }
}

与此同时,我也写了一些实验代码,测试一下Attribute的对象构造过程,结果是每调用一次GetCustomAttributes方法,就会创建一个全新的Attribute对象,实验代码简介:
先定义一个特性类:

public class BeinetAttribute : Attribute
{
    public BeinetAttribute()
    {
        Console.WriteLine("BeinetAttribute构造函数执行了");
    }
}

再定义一个使用了这个特性声明的类:

[Beinet]
public class BeinetDemo
{
}

下面是演示代码:

static void Main()
{
    var type = typeof(BeinetDemo);
    Console.WriteLine("第一次GetCustomAttributes:");
    var atts1 = type.GetCustomAttributes(false);
    Console.WriteLine("第二次GetCustomAttributes:");
    var atts2 = type.GetCustomAttributes(false);
    Console.WriteLine("2次读取对象是否相等:" + (atts1[0] == atts2[0]));
    Console.Read();
}

执行结果如下,可以看到调用2次GetCustomAttributes,生成了2个对象:

第一次GetCustomAttributes:
BeinetAttribute构造函数执行了
第二次GetCustomAttributes:
BeinetAttribute构造函数执行了
2次读取对象是否相等:False

所以,如果特性里有些属性是可变的,要注意不要频繁GetCustomAttributes,可以只读取一次,然后缓存起来,比如下面的缓存代码:

static ConcurrentDictionary<Type, List<Attribute>> _typeAtts =
    new ConcurrentDictionary<Type, List<Attribute>>();

public static List<Attribute> GetAttributes(Type type)
{
    var ret = _typeAtts.GetOrAdd(type, typeInner =>
    {
        var result = typeInner.GetCustomAttributes(false);
        return result.Select(item => (Attribute) item).ToList();
    });
    return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游北亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值