NetCore中怎么利用Transitional自定义注解事物

本篇文章给大家分享的是有关NetCore中怎么利用Transitional自定义注解事物,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

之前实现了NetCore实现自定义IOC容器注入,在Controller使用事物的过程中思考是否能够像Spring一样通过自定义注解实现事物管理,思路图如下

事物的动作拆分只需要根据当前执行线程划分Connection对象并开启事物即可,重点是在Emit代码织入过程中对异常捕捉的处理

处理过程中主要会用到BeginExceptionBlock开启try代码块,BeginCatchBlock开启catch代码块,EndExceptionBlock结束异常捕捉代码块

创建事物注解Transitional用来标记Controller中需要事物执行的方法

[AttributeUsage(AttributeTargets.Method)]
publicclassTransitional:System.Attribute
{
publicboolAutoRollBack{set;get;}

publicTransitional()
{
AutoRollBack=true;
}
}

Emit编织时需要注意异常捕捉时有返回值时建立全局变量返回,执行事物管理器类的静态方法直接使用call,例如ilOfMethod.Emit(OpCodes.Call, typeof(TransitionManage).GetMethod("DoRollBack")),同时Controller被拦截的方法需要标记Transitional注解且同时是虚方法

被代理类示例

publicclassTransitionalMovie{
[Transitional]publicvirtualvoidTest1(){
Console.WriteLine("Test1");

}

[Transitional]publicvirtualstringTest2(){
Console.WriteLine("Test2");thrownewException("111");return"Hello";
}

[Transitional(AutoRollBack=false)]publicvirtualvoidTest3(stringKey){
Console.WriteLine("Test3");
Console.WriteLine(Key);

}

IOC使用示例,IOC容器原理可参考c#通过Emit方式实现动态代理

varcontainer=newContainerBuilder();
container.RegisterType().EnableIntercept();
container.Build();
TransitionalMovietm=container.Resolve();
tm.Test1();stringresult=tm.Test2();
Console.WriteLine(result);
tm.Test3("世界第一等");

动态代理生成类反编译代码

动态代理包含异常拦截与事物的全部代码

publicstaticObjectCreateProxyObject(TypeInterfaceType,TypeImpType,TypeInterceptType,boolinheritMode=true,boolisInterceptAllMethod=true){stringnameOfAssembly=ImpType.Name+"ProxyAssembly";stringnameOfModule=ImpType.Name+"ProxyModule";stringnameOfType=ImpType.Name+"Proxy";varassemblyName=newAssemblyName(nameOfAssembly);
ModuleBuildermoduleBuilder=null;varassembly=AssemblyBuilder.DefineDynamicAssembly(assemblyName,AssemblyBuilderAccess.Run);
moduleBuilder=assembly.DefineDynamicModule(nameOfModule);
TypeBuildertypeBuilder;if(inheritMode)
{
typeBuilder=moduleBuilder.DefineType(
nameOfType,TypeAttributes.Public,ImpType);
}else{
typeBuilder=moduleBuilder.DefineType(
nameOfType,TypeAttributes.Public,null,new[]{InterfaceType});
}

InjectInterceptor(typeBuilder,ImpType,InterceptType,inheritMode,isInterceptAllMethod);vart=typeBuilder.CreateType();returnActivator.CreateInstance(t);
}privatestaticvoidInjectInterceptor(TypeBuildertypeBuilder,TypeImpType,TypeInterceptType,boolinheritMode,boolisInterceptAllMethod){#region变量定义//----变量定义----varconstructorBuilder=typeBuilder.DefineConstructor(
MethodAttributes.Public,CallingConventions.Standard,null);varilOfCtor=constructorBuilder.GetILGenerator();//----拦截类对象定义----if(InterceptType==null)
{
InterceptType=typeof(DefaultIntercept);
}//声明varfieldInterceptor=typeBuilder.DefineField("_interceptor",InterceptType,FieldAttributes.Private);//赋值ilOfCtor.Emit(OpCodes.Ldarg_0);
ilOfCtor.Emit(OpCodes.Newobj,InterceptType.GetConstructor(newType[0]));
ilOfCtor.Emit(OpCodes.Stfld,fieldInterceptor);#endregion#region代理对象定义//----实现类对象定义----//声明varfieldBeProxy=typeBuilder.DefineField("_beproxy",ImpType,FieldAttributes.Private);//赋值ilOfCtor.Emit(OpCodes.Ldarg_0);
ilOfCtor.Emit(OpCodes.Newobj,ImpType.GetConstructor(newType[0]));
ilOfCtor.Emit(OpCodes.Stfld,fieldBeProxy);
ilOfCtor.Emit(OpCodes.Ret);#endregion//----定义类中的方法----varmethodsOfType=ImpType.GetMethods(BindingFlags.Public|BindingFlags.Instance).Where(a=>a.IsVirtual).ToArray();string[]ignoreMethodName=new[]{"GetType","ToString","GetHashCode","Equals"};for(vari=0;ip.ParameterType).ToArray();//----定义方法名与参数----varmethodBuilder=typeBuilder.DefineMethod(
method.Name,
MethodAttributes.Public|MethodAttributes.Virtual,
CallingConventions.Standard,
method.ReturnType,
methodParameterTypes);//如果是泛型方法if(method.IsGenericMethod)
{//获取所有泛型参数类型定义Type[]Args=method.GetGenericArguments();
ListGenericArgNames=newList();for(intj=0;j

以上就是NetCore中怎么利用Transitional自定义注解事物,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注恰卡编程网行业资讯频道。

发布于 2021-07-29 22:00:00
分享
海报
206
上一篇:Python中怎么引用传递变量赋值 下一篇:PyTorch中Variable变量的作用是什么
目录

    忘记密码?

    图形验证码