예제 #1
0
 private static void ExcepionIntercept(ILGenerator ilGenerator, IInterceptor[] interceptors, LocalBuilder[] local)
 {
     var excepionInterceptors = interceptors.GetExcepionInterceptors();
     if (!excepionInterceptors.Any())
     {
         ilGenerator.Emit(OpCodes.Throw);
         return;
     }
     var invocationType = InternalDynamicTypeProvider.CreateType<IExceptionInvocation>();
     var setException = invocationType.GetMethod("set_Exception");
     var setInterceptedType = invocationType.GetMethod("set_InterceptedType");
     var setInterceptedInstance = invocationType.GetMethod("set_InterceptedInstance");
     var getExceptionHandled = invocationType.GetMethod("get_ExceptionHandled");
     var getExcepionInterceptMethod = typeof(IExceptionInterceptor).GetMethod("OnExcepion");
     var getExcepionInterceptorsMethod = typeof(InterceptorExtends).GetMethod("GetExcepionInterceptors");
     var exceptionLocal = ilGenerator.DeclareLocal(typeof(Exception));
     var interceptorLocal = ilGenerator.DeclareLocal(typeof(IExceptionInterceptor[]));
     var invocationLocal = ilGenerator.DeclareLocal(invocationType);
     var breakExceptionLable = ilGenerator.DefineLabel();
     ilGenerator.StoreLocal(exceptionLocal).LoadLocal(local[0]).Call(getExcepionInterceptorsMethod).StoreLocal(interceptorLocal);
     ilGenerator.New(invocationType.GetConstructor(Type.EmptyTypes)).StoreLocal(invocationLocal);
     ilGenerator.LoadLocal(invocationLocal).LoadLocal(exceptionLocal).Callvirt(setException);
     ilGenerator.LoadLocal(invocationLocal).LoadLocal(local[2]).Callvirt(setInterceptedType);
     ilGenerator.LoadLocal(invocationLocal).This().Callvirt(setInterceptedInstance);
     ilGenerator.ForEach(excepionInterceptors, (il, interceptor, index) =>
     il.LoadLocal(invocationLocal).Callvirt(getExceptionHandled).False(breakExceptionLable).LoadLocal(interceptorLocal).LoadArrayItem(index).
     LoadLocal(invocationLocal).Callvirt(getExcepionInterceptMethod)).MarkLabelFor(breakExceptionLable);
 }