项目地址:Google Code,GitHub
实现的特性有:
1. AOP
2. Dynamic Proxy
3. Minxins
4. Duck Typing
5. Design by Contract

基本示例


public class SimpleSamepleEntity
{public SimpleSamepleEntity(){Console.WriteLine("create SimpleSamepleEntity");}public virtual string Name { get; set; }public virtual int Age { get; set; }public override string ToString(){return string.Format("{{ Name: \"{0}\", Age: {1} }}", this.Name, this.Age);}
}
public class SimpleSampleInterceptor : IInterceptor
{private SimpleSamepleEntity _target;public SimpleSampleInterceptor(SimpleSamepleEntity target){this._target = target;}public object Intercept(InvocationInfo info){Console.WriteLine(">>Intercepting " + info.TargetMethod.Name);return info.TargetMethod.Invoke(this._target, info.Arguments);}
}
public class SimpleSampleWrapper : IInvokeWrapper
{private SimpleSamepleEntity _target;public SimpleSampleWrapper(SimpleSamepleEntity target){this._target = target;}public void BeforeInvoke(InvocationInfo info){Console.WriteLine(">>Intercepting " + info.TargetMethod.Name);}public object DoInvoke(InvocationInfo info){return info.TargetMethod.Invoke(this._target, info.Arguments);}public void AfterInvoke(InvocationInfo info, object returnValue){Console.WriteLine("<<Intercepted " + info.TargetMethod.Name + ", result: " + (returnValue == null ? "null" : returnValue.ToString()));}
}

使用代码:


ProxyFactory factory = new ProxyFactory();
SimpleSamepleEntity entity = new SimpleSamepleEntity() { Name = "Richie", Age = 99 };
SimpleSampleInterceptor interceptor = new SimpleSampleInterceptor(entity);
SimpleSamepleEntity proxy1 = factory.CreateProxy<SimpleSamepleEntity>(interceptor);
Console.WriteLine(proxy1.Name);
Console.WriteLine(proxy1.ToString());
Console.WriteLine("==============================");
SimpleSampleWrapper wrapper = new SimpleSampleWrapper(entity);
SimpleSamepleEntity proxy2 = factory.CreateProxy<SimpleSamepleEntity>(wrapper);
Console.WriteLine(proxy2.Name);
Console.WriteLine(proxy2.ToString());
Console.ReadKey();

运行结果:
   

说明:
1. LinFu的Dynamic Proxy有2种方式实现拦截器,即上面示例的IInterceptor和IInvokeWrapper接口
2. 与Castle Dynamic Proxy的不同之处在于,LinFu的拦截器只负责拦截功能,他并不维护目标真实对象,所以表现出来的差异有:
    a). 在拦截器接口中没有类似Castle的invocation.Proceed类似的方法,因为LinFu根本不知道目标真实对象在哪里。上面示例中我们在IInterceptor和IInvokeWrapper构造器中传入了目标对象,在拦截器接口方法中在_target对象上调用目标方法
    b). Castle在创建class proxy的时候,如果没有提供target,Castle会自己创建一个目标实体对象。而LinFu将interceptor与目标对象分离,所以在创建代理对象的时候不会创建目标对象
    c). 可以这样理解,LinFu的代理对象与Castle的interface proxy without target的行为基本一致。如果使用者也不处理target,则代理对象仅仅是一个拦截器,比Castle的class proxy要简洁
3. LinFu不像Castle,将proxy分为class proxy、interface proxy等类型,在LinFu中这些概念对使用者是透明的,但这里面也有些方面值得注意:
    a). 如果创建的是class proxy,则只能对virtual的方法进行拦截;如果创建的是interface proxy,非virtual的方法也可以实现拦截,这一点与Castle是一致的
    b). 如果创建的是interface proxy,即使目标对象override了ToString等方法,LinFu也无法通过info.TargetMethod.Invoke调用到目标对象的ToString方法
4. 拦截机制上的差异
    上面示例中,SimpleSamepleEntity的ToString方法中还调用了this.Name、this.Age,在Castle中这2个调用可以被拦截到,但LinFu中只能拦截到ToString方法

LinFu的代理对象都实现了IProxy接口,可以通过IProxy接口动态改变拦截器。比如上面的例子中,再实现一个拦截器:


public class AnotherInterceptor : IInterceptor
{public object Intercept(InvocationInfo info){Console.WriteLine(">>Intercepting " + info.TargetMethod.Name);return null;}
}
ProxyFactory factory = new ProxyFactory();
SimpleSamepleEntity entity = new SimpleSamepleEntity() { Name = "Richie", Age = 99 };
SimpleSampleInterceptor interceptor = new SimpleSampleInterceptor(entity);
SimpleSamepleEntity proxy = factory.CreateProxy<SimpleSamepleEntity>(interceptor);
Console.WriteLine("name: " + proxy.Name);
Console.WriteLine("entity: "+proxy.ToString());
AnotherInterceptor interceptor2 = new AnotherInterceptor();
(proxy as IProxy).Interceptor = interceptor2;
Console.WriteLine("name: " + proxy.Name);
Console.WriteLine("entity: " + proxy.ToString());
Console.ReadKey();

性能对比:
下图是作者做的一个与Castle DP的性能对比测试,都禁用掉了缓存,创建不同类型的代理对象。横轴是创建代理对象的个数,纵轴是所花的时间
   

准备看一下LinFu的DynamicObject、IoC,但这2个功能只在1.0的版本中才有,在后来新的LinFu.Core.dll、LinFu.DynamicProxy.dll程序集的基础上没法使用。github中最新的代码里面也没有DynamicObject这个对象,作者还在修改

参考:
Introducing the LinFu Framework, Part I - LinFu.DynamicProxy: A Lightweight Proxy Generator
Introducing the LinFu Framework, Part II: LinFu.DynamicObject – Adding Dynamic Language Features to Statically Typed Languages
Introducing the LinFu Framework, Part III: LinFu.Delegates-Lambda Arguments & Universal Event Handling
Introducing the LinFu Framework, Part IV: Simple.IOC – The Five Minute Inversion of Control Container
Introducing the LinFu, Part V: LinFu.DesignByContract2 – Adding Transparent Design by Contract Features to Any .NET Language
Introducing LinFu, Part VI: LinFu.AOP – Pervasive Method Interception and Replacement for Sealed Types in Any .NET Language

LinFu Dynamic Proxy - LinFu 2.3, LinFu.DynamicProxy 1.031相关推荐

  1. The bean ‘xxx‘ could not be injected as a ‘xxx‘ because it is a JDK dynamic proxy that implements:

    The bean 'xxx' could not be injected as a 'xxx' because it is a JDK dynamic proxy that implements: 问 ...

  2. The bean ‘Xxx‘ could not be injected as a ‘Xxx‘ because it is a JDK dynamic proxy that implements:x

    完成错误信息如下: *************************** APPLICATION FAILED TO START ***************************Descrip ...

  3. The bean 'llWebSocketHandler' could not be injected because it is a JDK dynamic proxy that implemen

    摘要:在做Spring Boot.WebSockets整合的时候,出现了bean注入失败的问题,错误异常如下: 一:异常信息: 2018-08-10 11:44:50.072 WARN 20296 - ...

  4. Spring aop(Aspectj)对dynamic proxy的类是无能为力的

    spring的aop是基于代理的,aspectj的aop的织入方式有以下几种: compile-time weaving, post-compile time weaving, and load-ti ...

  5. because it is a JDK dynamic proxy that implements问题 看这一篇就够了

    一.背景 开发中常见这个错误: The bean 'xxxService' could not be injected as a'com.xxxx.xxx.xxxService' because it ...

  6. The bean 'xxx' could not be injected as a 'xxx'because it is a JDK dynamic proxy that implements

    启动springboot项目的时候示以下错误 1 Error starting ApplicationContext. To display the conditions report re-run ...

  7. The bean ‘xxImpl‘ could not be injected as a ‘xxx‘ because it is a JDK dynamic proxy that implements

    项目启动报错:The bean 'xxxServiceImpl' could not be injected as a 'com.xxx.service.impl.xxxServiceImpl' be ...

  8. The bean ‘xxx‘ could not be injected as a ‘xxx‘because it is a JDK dynamic proxy that implements错误解决

    1.解决方法:使用@Autowired 2.@autowired和@resource注解的区别 区别: 1.@Autowired注解由Spring提供,只按照byType注入:@resource注解由 ...

  9. The bean ‘XXX‘ could not be injected because it is a JDK dynamic proxy

    1.看了网上的方法说先把mybatis-plus依赖注释掉,没有反应. 2.通过将Controller文件都注释掉,发现@Resource出问题了,有两个对象名相同 3.修改了其中一个名,果然解决

最新文章

  1. 一台服务器上起2个mysql服务
  2. 为什么你应该停止阅读新闻?
  3. 使用idea创建gradle的springboot工程
  4. datagrip替换字_DataGrip使用进阶-导航及搜索(一)
  5. 二叉树经典题之根据二叉树创建字符串(二叉树的括号表示法)
  6. 基于JAVA+Spring+MYSQL的婚纱摄影网站
  7. matlab 快速傅里叶变换函数(fft)编写
  8. python电子书合集
  9. PS2015下载PSCC2015安装教程
  10. No ip domain-lookup和Logging synchronous和Exec-timeout 0 0
  11. Cesium开发环境搭建的几种方法总结
  12. 魏巍专访丨合作半年拓客100+,他是如何做到的?
  13. linux Guest账户下如何更新默认的python版本
  14. 基于深度学习的语义分割
  15. 小波神经网络(时间序列预测)
  16. Python - names模块解析(海量英文名)
  17. python 实现zigzag排列
  18. Apache基于域名、端口、IP的虚拟主机配置(Centos 6.5)
  19. 辗转相除法+更相减损法求最大公约数
  20. 椭圆曲线加密和签名算法

热门文章

  1. block,inline和inline-block概念和区别
  2. UITests操作指南
  3. centos 6.5内核升级
  4. 从0开始的微服务架构:(一)重识微服务架构
  5. 英特尔九州云99Cloud OpenStack行业应用研讨会
  6. 蓝桥杯 兰顿蚂蚁(模拟)
  7. apache关于记录真实客户端ip和不记录健康检查日志
  8. Php pack unpack
  9. C# 一个操作Oracle的简易工具类(通过System.Data.OracleClient)
  10. Android 数据库之Cursor