MSIL Emit AOP
参考链接:
https://pieterderycke.wordpress.com/tag/reflection-emit/
http://www.moon-soft.com/doc/23252.htm
http://www.codeproject.com/Articles/18677/Dynamic-Assemblies-using-Reflection-Emit-Part-II-o
示例一:
public interface IProxy
{
void GetProxyInstance();
} public static class Util
{
public static void Before(string message)
{
Console.WriteLine( $"dynamic message: {message}" );
}
} public class TypeCreator
{
private readonly Type _targetType; public TypeCreator(Type targetType)
{
this._targetType = targetType;
} public Type Build()
{
var currentAppDomain = AppDomain.CurrentDomain;
var assemblyName = new AssemblyName {
Name = "_Aop_Assembly_" + this._targetType.Name
};
var assemblyBuilder = currentAppDomain.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Run );
var moduleBuilder = assemblyBuilder.DefineDynamicModule( "_Aop_Module_" + this._targetType.Name );
var implTypeName = "_Impl_" + this._targetType.Name;
var implTypeAttribute = TypeAttributes.Class | TypeAttributes.Public;
Type implTypeParent;
Type[] implTypeInterfaces; if( this._targetType.IsInterface )
{
implTypeParent = null;
implTypeInterfaces = new[] {
this._targetType
};
}
else
{
implTypeParent = this._targetType;
implTypeInterfaces = new Type[];
} var typeBuilder = moduleBuilder.DefineType( implTypeName, implTypeAttribute, implTypeParent, implTypeInterfaces );
var implTargetMethods = this._targetType.GetMethods(); foreach( var implTargetMethod in implTargetMethods )
{
if( implTargetMethod.IsVirtual )
{
var parameters = implTargetMethod.GetParameters();
var parameterTypes = new Type[parameters.Length]; for( var i = ; i < parameters.Length; i++ )
{
parameterTypes[i] = parameters[i].ParameterType;
} var methodBuilder = typeBuilder.DefineMethod( implTargetMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, implTargetMethod.ReturnType, parameterTypes ); var ilGen = methodBuilder.GetILGenerator(); ilGen.Emit( OpCodes.Ldstr, "Before Execute " + this._targetType.Name + ";" );
ilGen.Emit( OpCodes.Call, typeof( Util ).GetMethod( "Before", new Type[] {
typeof( string )
} ) );
ilGen.Emit( OpCodes.Ret );
}
} return typeBuilder.CreateType();
}
} // 调用示例:
var tc = new TypeCreator( typeof( IProxy ) );
var dynamicType = tc.Build();
var proxy = (IProxy) Activator.CreateInstance( dynamicType ); proxy.GetProxyInstance();
示例二:
public class ViewModelBase
{
protected void RaisePropertyChanged( string propertyName )
{
Console.WriteLine( $"PropertyName: {propertyName}" );
}
} [AttributeUsage(AttributeTargets.Property)]
public class RaisePropertyChangedAttribute : Attribute
{ } public class SampleViewModel : ViewModelBase
{
[RaisePropertyChanged]
public virtual string SomeProperty { get; set; }
} public static class ReflectionEmitViewModelFactory
{
public static T CreateInstance<T>()
where T : ViewModelBase
{
Type vmType = typeof(T); VerifyViewModelType(vmType); // Create everything required to get a module builder
AssemblyName assemblyName = new AssemblyName("SmartViewModelDynamicAssembly");
AppDomain domain = AppDomain.CurrentDomain;
AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
//AssemblyBuilderAccess.RunAndSave);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); string dynamicTypeName = Assembly.CreateQualifiedName(vmType.AssemblyQualifiedName, "Smart" + vmType.Name); TypeBuilder typeBuilder = moduleBuilder.DefineType(dynamicTypeName,
TypeAttributes.Public | TypeAttributes.Class, vmType); MethodInfo raisePropertyChangedMethod = typeof(ViewModelBase).GetMethod("RaisePropertyChanged",
BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null); foreach( PropertyInfo propertyInfo in FindNotifyPropertyChangCandidates<T>() )
UpdateProperty(propertyInfo, typeBuilder, raisePropertyChangedMethod); Type dynamicType = typeBuilder.CreateType(); return (T)Activator.CreateInstance(dynamicType);
} private static void VerifyViewModelType( Type vmType )
{
if( vmType.IsSealed )
throw new InvalidOperationException("The specified view model type is not allowed to be sealed.");
} private static IEnumerable<PropertyInfo> FindNotifyPropertyChangCandidates<T>()
{
return from p in typeof(T).GetProperties()
where p.GetSetMethod() != null && p.GetSetMethod().IsVirtual &&
p.GetCustomAttributes(typeof(RaisePropertyChangedAttribute), false).Length >
select p;
} private static void UpdateProperty( PropertyInfo propertyInfo, TypeBuilder typeBuilder,
MethodInfo raisePropertyChangedMethod )
{
// Update the setter of the class
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyInfo.Name,
PropertyAttributes.None, propertyInfo.PropertyType, null); // Create set method
MethodBuilder builder = typeBuilder.DefineMethod("set_" + propertyInfo.Name,
MethodAttributes.Public | MethodAttributes.Virtual, null, new Type[] { propertyInfo.PropertyType });
builder.DefineParameter(, ParameterAttributes.None, "value");
ILGenerator generator = builder.GetILGenerator(); // Add IL code for set method
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Call, propertyInfo.GetSetMethod()); // Call property changed for object
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldstr, propertyInfo.Name);
generator.Emit(OpCodes.Callvirt, raisePropertyChangedMethod);
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ret);
propertyBuilder.SetSetMethod(builder);
}
} //调用示例:
SampleViewModel viewModel = ReflectionEmitViewModelFactory.CreateInstance<SampleViewModel>();
viewModel.SomeProperty = "";
MSIL Emit AOP的更多相关文章
- .net动态代理-EMIT,AOP实现
动态代理实现原理: 通过动态基础目标类,重写目标虚方法,.net中实现手段-il Emit.Proxy项目源码,https://github.com/1448376744/Emit.Proxy 以下是 ...
- 常见的 emit 实现 AOP demo
0. 前言 上接:思想无语言边界:以 cglib 介绍 AOP 在 java 的一个实现方式 作为第四篇,我们回顾一下 csharp 里面比较常见动态编织实现方式emit 内容安排如下: emit a ...
- C#基础之泛型
1.泛型的本质 泛型的好处不用多说,在.NET中我看到有很多技术都是以泛型为基础的,不过因为不懂泛型而只能对那些技术一脸茫然.泛型主要用于集合类,最主要的原因是它不需要装箱拆箱且类型安全,比如很常用的 ...
- ILGenerator.Emit动态 MSIL编程(一)之基础
首先在Framework中,Emit相关的类基本都存在于System.Reflection.Emit命名空间下.可见Emit是作为反射的一个元素存在的. Emit能够实现什么?为什么要学习Emit?首 ...
- C#利用Emit反射实现AOP,以及平台化框架封装思路
C#利用Emit反射实现AOP,以及平台化框架封装思路 这是前两天扒的一段动态代理AOP代码,用的Emit反射生成子类来实现代理模式,在这里做个小笔记,然后讨论一下AOP框架的实现思路. 首先是主函数 ...
- AOP从静态代理到动态代理 Emit实现
[前言] AOP为Aspect Oriented Programming的缩写,意思是面向切面编程的技术. 何为切面? 一个和业务没有任何耦合相关的代码段,诸如:调用日志,发送邮件,甚至路由分发.一切 ...
- C# 使用Emit实现动态AOP框架 (三)
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- C# 使用Emit实现动态AOP框架 (二)
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
- C# 使用Emit实现动态AOP框架 (一)
目 录 C# 使用Emit实现动态AOP框架 (一) C# 使用Emit实现动态AOP框架 (二) C# 使用Emit实现动态AOP框架 (三) C# 使用Emit实现动态AOP框架 进阶篇之异常处 ...
随机推荐
- wkhtmltopdf乱码解决方案
在CentOS下使用wkhtmltopdf将html页面转换成pdf的时候对于某些页面可能会出现转换成的pdf中很多字符乱码的情况,更怪异的是直接在命令行下运行一切正常,但在httpd+php下使用却 ...
- Microsoft JScript 运行时错误: '$' 未定义
在运行MVC Music Store时Visual Studio 捕捉到此错误: Microsoft JScript 运行时错误: '$' 未定义 可能是引用的Scripts 引用出错,检查当前文件中 ...
- 使用composer管理php项目
composer global require "fxp/composer-asset-plugin:~1.1.1" composer create-project --prefe ...
- jQuery的编码标准和最佳实践
不知道在哪里看到了这篇关于jQuery编码的文章,挺实用的,恰好最近在研究jQuery的基础知识,今天打开收藏夹来翻译一下,原文的英语不难,但是内容很实用,可能有大神已经翻译过了,大家看精华就行了. ...
- Cookie实现商品浏览记录--方式一:Java实现
方式一:Java代码方式实现:此种方式实现思路较为顺畅.难点在于,如何实现将最近浏览的产品显示在最前面:实现方式是借助LinkedList提供的remove()方法,先将此id从列表中移除,然后再借助 ...
- 【原】mysql慢日志分析
pt-query-digest slowquery.log --since "2016-01-23 10:50:00"
- AutoCAD系统变量一览表
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; t ...
- html基础 2
HTML 文本格式化实例 (我不知道为什么“正常显示文本”这几个字不用加标签,虽然它有在<body>标签内) <html> <body> <b>文本为黑 ...
- 使用Struts2搭建登录注册示例
使用Struts2来搭建mvc网站框架还是比较容易的,Struts2提供了各项辅助功能,保证了web开发的快速方便.下面使用struts2来搭建一个登录注册示例. 0 项目结构截图 1 搭建Strut ...
- SQL Server 2008通过LinkServer连接MySQL
链接过程就不过多描述了,搜索下都有一大堆的内容. 链接成功以后,如何调用的问题,通过“编写select脚本”的方式生成的脚本如下: [备注:asset_manager是数据库名,admin是表名] - ...