c# emit 实现类的代理
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit; namespace EmitCreateDynamicProxy
{
class Program
{
static void Main(string[] args)
{
var command = Proxy.Of<Command>();
command.Execute(); Console.ReadLine();
}
} public class Command
{
public virtual void Execute()
{ Console.WriteLine("Hello Kitty!"); }
} public class Interceptor
{
public object Invoke(object @object, string @method, object[] parameters)
{
Console.WriteLine(
string.Format(" before invoke [{0}]...", @method)); var retObj = @object.GetType().GetMethod(@method).Invoke(@object, parameters); Console.WriteLine(
string.Format(" after invoke [{0}]...", @method)); return retObj;
}
} public class Proxy
{
public static T Of<T>()
{
string nameOfAssembly = typeof(T).Name + "ProxyAssembly";
string nameOfModule = typeof(T).Name + "ProxyModule";
string nameOfType = typeof(T).Name + "Proxy"; var assemblyName = new AssemblyName(nameOfAssembly);
var assembly = AppDomain.CurrentDomain
.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var moduleBuilder = assembly.DefineDynamicModule(nameOfModule); var typeBuilder = moduleBuilder.DefineType(
nameOfType, TypeAttributes.Public,typeof(T)); InjectInterceptor<T>(typeBuilder); var t = typeBuilder.CreateType(); return (T)Activator.CreateInstance(t) ;
} private static void InjectInterceptor<T>(TypeBuilder typeBuilder)
{
// ---- define fields ---- var fieldInterceptor = typeBuilder.DefineField(
"_interceptor", typeof(Interceptor), FieldAttributes.Private); // ---- define costructors ---- var constructorBuilder = typeBuilder.DefineConstructor(
MethodAttributes.Public, CallingConventions.Standard, null);
var ilOfCtor = constructorBuilder.GetILGenerator(); ilOfCtor.Emit(OpCodes.Ldarg_0);
ilOfCtor.Emit(OpCodes.Newobj, typeof(Interceptor).GetConstructor(new Type[]));
ilOfCtor.Emit(OpCodes.Stfld, fieldInterceptor);
ilOfCtor.Emit(OpCodes.Ret); // ---- define methods ---- var methodsOfType = typeof(T).GetMethods(BindingFlags.Public | BindingFlags.Instance); for (var i = ; i < methodsOfType.Length; i++)
{
var method = methodsOfType[i];
var methodParameterTypes =
method.GetParameters().Select(p => p.ParameterType).ToArray(); var methodBuilder = typeBuilder.DefineMethod(
method.Name,
MethodAttributes.Public | MethodAttributes.Virtual,
CallingConventions.Standard,
method.ReturnType,
methodParameterTypes); var ilOfMethod = methodBuilder.GetILGenerator();
ilOfMethod.Emit(OpCodes.Ldarg_0);
ilOfMethod.Emit(OpCodes.Ldfld, fieldInterceptor); // create instance of T
ilOfMethod.Emit(OpCodes.Newobj, typeof(T).GetConstructor(new Type[]));
ilOfMethod.Emit(OpCodes.Ldstr, method.Name); // build the method parameters
if (methodParameterTypes == null)
{
ilOfMethod.Emit(OpCodes.Ldnull);
}
else
{
var parameters = ilOfMethod.DeclareLocal(typeof(object[]));
ilOfMethod.Emit(OpCodes.Ldc_I4, methodParameterTypes.Length);
ilOfMethod.Emit(OpCodes.Newarr, typeof(object));
ilOfMethod.Emit(OpCodes.Stloc, parameters); for (var j = ; j < methodParameterTypes.Length; j++)
{
ilOfMethod.Emit(OpCodes.Ldloc, parameters);
ilOfMethod.Emit(OpCodes.Ldc_I4, j);
ilOfMethod.Emit(OpCodes.Ldarg, j + );
ilOfMethod.Emit(OpCodes.Stelem_Ref);
}
ilOfMethod.Emit(OpCodes.Ldloc, parameters);
} // call Invoke() method of Interceptor
ilOfMethod.Emit(OpCodes.Callvirt, typeof(Interceptor).GetMethod("Invoke")); // pop the stack if return void
if (method.ReturnType == typeof(void))
{
ilOfMethod.Emit(OpCodes.Pop);
} // complete
ilOfMethod.Emit(OpCodes.Ret);
}
}
}
}
c# emit 实现类的代理的更多相关文章
- .NET高级特性-Emit(2)类的定义
在上一篇博文发了一天左右的时间,就收到了博客园许多读者的评论和推荐,非常感谢,我也会及时回复读者的评论.之后我也将继续撰写博文,梳理相关.NET的知识,希望.NET的圈子能越来越大,开发者能了解/深入 ...
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- .net 代理类(WebService代理类的详解 )
http://hi.baidu.com/654085966/item/53ee8c0f108ad78202ce1b1d -----------转自 客户端调用Web Service的方式我现在知道 ...
- cglib动态代理是通过继承父类的方式进行代理的 不是通过接口方式进行动态代理的 因此可以对普通的类进行代理
cglib动态代理是通过继承父类的方式进行代理的 不是通过接口方式进行动态代理的
- AOP从静态代理到动态代理 Emit实现
[前言] AOP为Aspect Oriented Programming的缩写,意思是面向切面编程的技术. 何为切面? 一个和业务没有任何耦合相关的代码段,诸如:调用日志,发送邮件,甚至路由分发.一切 ...
- WCF:传输EntityFramework 实体类的POCO 代理
WCF传输EntityFramework 实体类的POCO 代理 Windows Communication Foundation (WCF) 不能对代理进行直接序列化或反序列化,因为 DataCon ...
- EF容器---代理类对象
#region 修改--官方的修改是,先查询,然后修改 /// <summary> /// 修改--官方的修改是,先查询,然后修改 /// </summary> static ...
- Java通过代理类实现数据库DAO操作
下面的所有代码示例都取自李兴华的<Java Web开发实战经典>的随书源码,因为觉得设计得很好,所以将代码摘录下来作成笔记. 首先,我们在一个java文件中定义要存储的结构类型: impo ...
- 深度模拟java动态代理实现机制系类之一
上一篇博客是最基本的动态代理原理的实现,因为其固定了接口,固定了代理方法,以及固定了代理的类型,接下来的博客系类将一步步渐入深度介绍java的动态代理的实现原理 ******************* ...
随机推荐
- Shell 环境中的输入输出重定向
Linux Shell 环境中的输入输出重定向,用符号<和>来表示.0.1和2分别表示标准输入.标准输出和标准错误. 1.重定向标准输出到文件: cat fo > foo.txt 2 ...
- c# dynamic,maybe I should say it is just some shortcut for "Object", box and unbox, without the cast
dynamic: void Main() { var b="2"; dynamic a="2"; if(a.GetType()==typeof(int))b+= ...
- js判断手机的左右滑动
js代码 $(function() { function judge() { var startx;//让startx在touch事件函数里是全局性变量. var endx; var el = doc ...
- 键盘事件keydown、keypress、keyup
事件触发顺序:keydown - > keypress - > keyup 中文输入法: firfox:输入触发keydown,回车确认输入触发keyup chrome:输入触发k ...
- Linux常用命令使用
系统基础相关 使用root用户的环境变量切换到root用户 su - 显示当前工作路径 pwd 显示当前系统默认语言及键盘布局 localectl 显示系统中能支持的所有语言 localectl li ...
- LeetCode OJ--Same Tree
https://oj.leetcode.com/problems/same-tree/ 判断两个二叉树,是否相等. 深搜 /** * Definition for binary tree * stru ...
- 解决WCF部署到IIS出现“证书必须具有能够进行密钥交换的私钥,该进程必须具有访问私钥的权限”
访问WCF服务时,出现异常详细信息: System.Security.Cryptography.CryptographicException: 密钥集不存在.ArgumentException: 证书 ...
- 将Map<String, List<Map<String,Object>>>进行排序
首先我贴上我的代码,刚开始我也不知道怎么排序还写了一些方法,最后请教群里的大神解决了 public Map<String, List<Map<String,Object>> ...
- Oracle SID爆破工具SidGuess
Oracle SID爆破工具SidGuess 在Oracle中,SID是System IDentifier的缩写.SID是一个数据库的唯一标识符.当用户希望远程连接Oracle数据库时,则需要知道 ...
- Light oj 1095 - Arrange the Numbers (组合数学+递推)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1095 题意: 给你包含1~n的排列,初始位置1,2,3...,n,问你刚好固定 ...