public void Weave(ILGenerator ilGenerator) { var typeofType = typeof(Type); var typeofObject = typeof(object); FieldBuilder contractFieldBuilder = null; LocalBuilder typesArrayLocalBuilder = null; LocalBuilder tempTypesArrayLocalBuilder = null; var typeofArrayOfTypes = typeofType.MakeArrayType(); var weavingSettings = aspectWeavingSettings.WeavingSettings; var getTypeFromHandleMethodInfo = typeofType.GetMethod("GetTypeFromHandle"); var localBuilderRepository = aspectWeavingSettings.LocalBuilderRepository; typesArrayLocalBuilder = localBuilderRepository.Declare(() => { return ilGenerator.DeclareLocal(typeofArrayOfTypes); }); tempTypesArrayLocalBuilder = ilGenerator.DeclareLocal(typeofArrayOfTypes); ilGenerator.EmitPushInteger(parameters.Length); ilGenerator.Emit(OpCodes.Newarr, typeofType); ilGenerator.EmitStoreLocal(tempTypesArrayLocalBuilder); parameters.ForEach((parameter, i) => { var isByRef = parameter.IsByRef; if (isByRef) { parameter = parameter.GetElementType(); } ilGenerator.EmitLoadLocal(tempTypesArrayLocalBuilder); ilGenerator.EmitPushInteger(i); ilGenerator.Emit(OpCodes.Ldtoken, parameter); ilGenerator.Emit(OpCodes.Call, getTypeFromHandleMethodInfo); if (isByRef) { ilGenerator.Emit(OpCodes.Callvirt, typeofType.GetMethod("MakeByRefType")); } ilGenerator.Emit(OpCodes.Stelem_Ref); }); ilGenerator.EmitLoadLocal(tempTypesArrayLocalBuilder); ilGenerator.EmitStoreLocal(typesArrayLocalBuilder); ilGenerator.EmitLoadArg(0); contractFieldBuilder = weavingSettings.TypeDefinition.GetFieldBuilder(weavingSettings.ContractType); ilGenerator.Emit(OpCodes.Ldfld, contractFieldBuilder); ilGenerator.Emit(OpCodes.Callvirt, typeofObject.GetMethod("GetType")); ilGenerator.Emit(OpCodes.Ldstr, method.Name); ilGenerator.EmitLoadLocal(typesArrayLocalBuilder); ilGenerator.Emit(OpCodes.Callvirt, typeofType.GetMethod("GetMethod", new[] { typeof(string), typeof(Type[]) })); ilGenerator.EmitStoreLocal(methodLocalBuilder); }
public void Weave(ILGenerator ilGenerator) { var typeofException = typeof(Exception); LocalBuilder exceptionLocalBuilder = null; var typeofFlowBehavior = typeof(FlowBehavior); LocalBuilder flowBehavoiurLocalBuilder = null; var afterRethrowLabel = ilGenerator.DefineLabel(); var throwFlowBehaviorLabel = ilGenerator.DefineLabel(); var rethrowFlowBehaviorLabel = ilGenerator.DefineLabel(); var argsImplLocalBuilder = localBuilderRepository.Get(aspectArgumentType); var jumpTable = new[] { throwFlowBehaviorLabel, rethrowFlowBehaviorLabel }; var setExceptionMethodInfo = aspectArgumentType.GetProperty("Exception").GetSetMethod(); var flowBehaviorMethodInfo = aspectArgumentType.GetProperty("FlowBehavior").GetGetMethod(); exceptionLocalBuilder = localBuilderRepository.GetOrDeclare(typeofException, () => { return ilGenerator.DeclareLocal(typeofException); }); flowBehavoiurLocalBuilder = localBuilderRepository.GetOrDeclare(typeofFlowBehavior, () => { return ilGenerator.DeclareLocal(typeofFlowBehavior); }); ilGenerator.BeginCatchBlock(typeofException); ilGenerator.EmitStoreLocal(exceptionLocalBuilder); ilGenerator.EmitLoadLocal(argsImplLocalBuilder); ilGenerator.EmitLoadLocal(exceptionLocalBuilder); ilGenerator.Emit(OpCodes.Callvirt, setExceptionMethodInfo); catchWeavers.ForEach(weaver => weaver.Weave(ilGenerator)); ilGenerator.EmitLoadLocal(argsImplLocalBuilder); ilGenerator.Emit(OpCodes.Callvirt, flowBehaviorMethodInfo); ilGenerator.EmitStoreLocal(flowBehavoiurLocalBuilder); ilGenerator.EmitLoadLocal(flowBehavoiurLocalBuilder); ilGenerator.EmitPushInteger(1); ilGenerator.Emit(OpCodes.Sub); ilGenerator.Emit(OpCodes.Switch, jumpTable); ilGenerator.Emit(OpCodes.Br_S, afterRethrowLabel); ilGenerator.MarkLabel(throwFlowBehaviorLabel); ilGenerator.EmitLoadLocal(exceptionLocalBuilder); ilGenerator.Emit(OpCodes.Throw); ilGenerator.MarkLabel(rethrowFlowBehaviorLabel); ilGenerator.Emit(OpCodes.Rethrow); ilGenerator.MarkLabel(afterRethrowLabel); }