目的:

可以将castle.dynamicProxy当成代码生成器,快速的生成自己想的代码.这个库经历了这么多年的测试,应该可以用了:D

概念:

IInterceptor:拦截器

当方法(属性的本质是两个方法的组合)被调用时,则执行这个拦截器的代码.

但是,默认情况下,一个方法的调用被生成了一个拦截器.如果用于DC代码生成,这似乎有点浪费资源.

public class SimpleLogInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine(">>" + invocation.Method.Name);
invocation.Proceed();
}
}

测试:

ProxyGenerator generator = new ProxyGenerator();
SimpleSamepleEntity entity = generator.CreateClassProxy<SimpleSamepleEntity>( new SimpleLogInterceptor(), new CallingLogInterceptor()); //这里可以指定多个拦截器
entity.Name = "Richie";
entity.Age = ;
Console.WriteLine("The entity is: " + entity);
Console.WriteLine("Type of the entity: " + entity.GetType().FullName);
Console.ReadKey();

 IInterceptorSelector 与 IProxyGenerationHook

实际中并不一定所有方法都需要运用全部的拦截器,对方法调用有选择性的选择拦截器有2种方式,例如:

public class InterceptorSelector : IInterceptorSelector
{
public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
{
if (method.Name.StartsWith("set_")) return interceptors; //这里可以决定什么的方法返回什么样的拦截器
else return interceptors.Where(i => i is CallingLogInterceptor).ToArray<IInterceptor>();
}
}
public class InterceptorFilter : IProxyGenerationHook
{
public bool ShouldInterceptMethod(Type type, MethodInfo memberInfo)
{
return memberInfo.IsSpecialName &&
(memberInfo.Name.StartsWith("set_") || memberInfo.Name.StartsWith("get_")); //什么样的方法可以被拦截?
}
public void NonVirtualMemberNotification(Type type, MemberInfo memberInfo)
{
      //类型为非虚方法时,这里可以得到提示,将被调用
}
public void MethodsInspected()
{
}
}

测试代码:

ProxyGenerator generator = new ProxyGenerator();
var options = new ProxyGenerationOptions(new InterceptorFilter()) { Selector = new InterceptorSelector() };
SimpleSamepleEntity entity = generator.CreateClassProxy<SimpleSamepleEntity>(
options,
new SimpleLogInterceptor(), new CallingLogInterceptor());
entity.Name = "Richie";
entity.Age = ;
Console.WriteLine("The entity is: " + entity);
Console.WriteLine("Type of the entity: " + entity.GetType().FullName);
Console.ReadKey();

IProxyGenerationHook接口决定整个方法是否运用拦截器,他是在动态构造代理类型的时候使用的;而IInterceptorSelector接口决定某个方法该运用哪些拦截器,他在每次调用被拦截的方法时执行
上面的示例只对setter和getter方法进行拦截,并且对getter方法只使用CallingLogInterceptor这个拦截器

导出、生成代理类型
Castle Dynamic Proxy允许我们将运行时生成的代理类型生成dll文件存到磁盘上,下次启动时通过加载这个dll文件可以避免动态生成代理类型

var scope = new ModuleScope(
true,
ModuleScope.DEFAULT_ASSEMBLY_NAME,
ModuleScope.DEFAULT_FILE_NAME,
"DynamicProxyTest.Proxies",
"DynamicProxyTest.Proxies.dll");
var builder = new DefaultProxyBuilder(scope);
var generator = new ProxyGenerator(builder);
var options = new ProxyGenerationOptions(new InterceptorFilter())
{
Selector = new InterceptorSelector()
};
SimpleSamepleEntity entity = generator.CreateClassProxy<SimpleSamepleEntity>(
options,
new SimpleLogInterceptor(), new CallingLogInterceptor());
IStorageNode node = generator.CreateInterfaceProxyWithTargetInterface<IStorageNode>(
new StorageNode("master")
, new DualNodeInterceptor(new StorageNode("slave"))
, new CallingLogInterceptor());
options = new ProxyGenerationOptions();
options.AddMixinInstance(new ClassA());
ClassB objB = generator.CreateClassProxy<ClassB>(options, new CallingLogInterceptor());
scope.SaveAssembly(false);

注意:上面用到的拦截器和其他测试类都必须加上[Serializable]属性
可以用reflector查看生成的dll,大致了解代理对象是如何工作的
启动时,可以使用
scope.LoadAssemblyIntoCache(assembly);
将生成的代理类型加载到内存中,其中assembly需要我们手动加载

参考原文:

http://www.cnblogs.com/RicCC/archive/2010/03/15/castle-dynamic-proxy.html

castle.dynamicProxy学习笔记的更多相关文章

  1. Castle DynamicProxy基本用法(AOP)

    本文介绍AOP编程的基本概念.Castle DynamicProxy(DP)的基本用法,使用第三方扩展实现对异步(async)的支持,结合Autofac演示如何实现AOP编程. AOP 百科中关于AO ...

  2. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  3. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  4. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  5. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  6. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  7. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  8. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  9. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

随机推荐

  1. Mysql 漏洞利用(越权读取文件,实战怎么从低权限拿到root密码)[转]

    cnrstar (Be My Personal Best!) | 2014-05-20 21:58 众所周知,Mysql的用户在没有File权限情况下是无法通过Load_file读文件或者通过into ...

  2. IM——技术方案

    一. 即时通讯技术方案 1. 第三方SDK: 环信, 融云, 网易云信, 腾讯 中小型公司/初创型: 建议使用第三方. 好处: 快, 符合快速开发的需求, 自己和后台人员不需要做什么操作 缺点: 你的 ...

  3. Python 3 实现定义跨模块的全局变量和使用

    尽管某些书籍上总是说避免使用全局变量,但是在实际的需求不断变化中,往往定义一个全局变量是最可靠的方法,但是又必须要避免变量名覆盖. Python 中 global 关键字可以定义一个变量为全局变量,但 ...

  4. 1088. [SCOI2005]扫雷Mine【网格DP】

    Description 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来.万圣节到了 ,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子 ...

  5. 3、JVM--垃圾回收期和内存分配策略(2)

    3.5.垃圾收集器 如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现.Java虚拟机规范中对垃圾收集器应该如何实现并没有任何规定,因此不同的厂商.不同版本的虚拟机所提供的垃圾收集 ...

  6. h5py

    解决办法: sudo apt-get install libhdf5-dev sudo apt-get install python-h5py

  7. MySQL(三)架构

    和其他数据库相比,MySQL有点与众不同,他的架构可以在多种不同场景中应用并发挥好的作用,但同时也会带来一点选择上的困难.MySQL并不完美,却足够灵活,能够适应高要求的环境.为了充分发挥MySQL的 ...

  8. 算法练习——最长公共子序列的问题(LCS)

    问题描述: 对于两个序列X和Y的公共子序列中,长度最长的那个,定义为X和Y的最长公共子序列.X  Y   各自字符串有顺序,但是不一定需要相邻. 最长公共子串(Longest Common Subst ...

  9. 最近邻规则分类(k-Nearest Neighbor )机器学习算法python实现

    综述 Cover和Hart在1968年提出了最初的近邻算法 是分类(classification)算法 输入基于实例的学习(instance-based learning),惰性学习(lazy lea ...

  10. 强连通分量算法·$tarjan$初探

    嗯,今天好不容易把鸽了好久的缩点给弄完了--感觉好像--很简单? 算法的目的,其实就是在有向图上,把一个强连通分量缩成一个点--然后我们再对此搞搞事情,\(over\) 哦对,时间复杂度很显然是\(\ ...