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的动态代理的实现原理 ******************* ...
随机推荐
- idea如何设置类头注释和方法注释(带注释模板)
1.idea类注释 打开:file->setting->Editor->Filr and Code Templates->Includes->File Header 类注 ...
- pat 甲级 1135. Is It A Red-Black Tree (30)
1135. Is It A Red-Black Tree (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yu ...
- 洛谷 [P2341] 受欢迎的牛
强连通分量 一个结论: 在有向图中, 一个联通块能被所有点遍历当且仅当图中只有一个连通块出度为零 #include <iostream> #include <cstdio> # ...
- Codeforces Round #393 (Div. 2)
A. Petr and a calendar time limit per test:2 seconds memory limit per test:256 megabytes input:stand ...
- POJ3104 Drying
Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13703 Accepted: 3527 Description It i ...
- 【HDOJ5555】Immortality of Frog(状压DP)
题意:给你一个NxN的网格,第N行的每一列都有个青蛙,这些青蛙只会往上走, 上帝会在每个膜中随机等概率放一个长生不老的药, 一共有N个膜,每个膜覆盖一些区间,如果这个区间恰好为N那么就是好膜,否则是坏 ...
- jsp和java获取文件或路径
1.如何获得当前文件路径常用:(1).Test.class.getResource("")得到的是当前类FileTest.class文件的URI目录.不包括自己!(2).Test. ...
- [SaltStack] salt-minion启动流程
SaltStack源码阅读 前面理了下salt-master的启动流程, 这次来看看salt-minion的启动流程. 启动salt-minion方法: /etc/init.d/salt-minion ...
- 字符串hash-26进制与10进制互相转换
Lovekey http://acm.hdu.edu.cn/showproblem.php?pid=2100 #include <bits/stdc++.h> using namespac ...
- Wannafly交流赛1 B 硬币[数学思维/贪心]
链接:https://www.nowcoder.com/acm/contest/69/B来源:牛客网 蜥蜴的生日快到了,就在这个月底! 今年,蜥蜴的快乐伙伴之一壁虎想要送好多个1元硬币来恶整蜥蜴. 壁 ...