AOP:Aspect oriented programming 面向切面编程,AOP 是 OOP(面向对象编程)的一种延续。
解决:在不改变原有业务逻辑的情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。
AOP利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的行为封装到一个可重用模块。
Autofac AOP的使用
安装Autofac 、安装Autofac.Extras.DynamicProxy
需要实现接口:IInterceptor
public class LogInterceptor : IInterceptor
{
// invocation:将要拦截的方法
public void Intercept(IInvocation invocation)
{
// 执行日志保留记录
Console.WriteLine("---在方法执行前记录日志---");
// 执行拦截的方法逻辑
invocation.Proceed();
Console.WriteLine("---在方法执行后记录日志---");
}
}
public void Intercept(IInvocation invocation)
{
Stopwatch sw = new Stopwatch();
sw.Start();
invocation.Proceed();
sw.Stop();
Console.WriteLine("MonitorInterceptor 本次方法共耗时:" + sw.ElapsedMilliseconds);
}
就在注册IOC的地方,注册类型拦截器就好
builder.RegisterType<LogInterceptor>();
builder.Regis terType<MonitorInterceptor>();
1、EnableInterfaceInterceptors:基于接口的拦截器
2、EnableClassInterceptors:基于类的拦截器
builder.RegisterType<MainViewModel>()
.InterceptedBy(typeof(LogInterceptor))
.InterceptedBy(typeof(MonitorInterceptor))
.EnableClassInterceptors();
public virtual void DoExport()
{
Console.WriteLine("触发了MainViewModel中的Export方法");
}
public virtual void DoSave(string args)
{
Thread.Sleep(10);
Console.WriteLine("触发了MainViewModel中的Save方法");
}
可以发现,我写的log是在方法执行前执行的,但是并没有在业务逻辑层写写对应的代码,就在IOC中加入拦截器。
动态代理--核心逻辑
static T CreateInstanceWithProxy<T>()
{
// 创建动态程序集和模块
AssemblyName assemblyName = new AssemblyName("DynamicAssembly");
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicModule");
// 创建一个新的类,并让它继承自ParentClass
TypeBuilder typeBuilder = moduleBuilder.DefineType(
typeof(T).Name + "__DynamicClass__",
TypeAttributes.Public,
typeof(T));
// 定义要重写的方法
MethodInfo[] mis = typeof(T).GetMethods();
foreach (MethodInfo mi in mis)
{
Type[] param_types = mi.GetParameters().Select(p => p.ParameterType).ToArray();
MethodBuilder methodBuilder = typeBuilder.DefineMethod(
mi.Name,// "Logout",
MethodAttributes.Public | MethodAttributes.Virtual,
mi.ReturnType, //typeof(void),
param_types // Type.EmptyTypes
);
// 获取方法的IL生成器
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
// 编写方法体指令
ilGenerator.Emit(OpCodes.Ldstr, $"[{mi.Name}] 方法执行前--Hello from dynamic method!");
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
ilGenerator.Emit(OpCodes.Ldarg_0);// 加载this指针
if (param_types.Length > 0)
{
ilGenerator.Emit(OpCodes.Ldarg_1);// 加载参数input
}
ilGenerator.Emit(OpCodes.Call, mi); // 调用基类的方法
//ilGenerator.EmitWriteLine("DynamicClass.MethodToOverride");
ilGenerator.Emit(OpCodes.Ldstr, $"[{mi.Name}] 方法执行后--Hello from dynamic method!");
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
ilGenerator.Emit(OpCodes.Ret);
}
// 创建类型
Type dynamicType = typeBuilder.CreateTypeInfo().AsType();
// 创建类的实例并调用重写的方法 创建代理类型
T instance = (T)Activator.CreateInstance(dynamicType);
return instance;
}