public ObserverGrain() { GrainType = GetType(); var handlerAttributes = GrainType.GetCustomAttributes(typeof(HandlerAttribute), false); if (handlerAttributes.Length > 0) { handlerAttribute = (HandlerAttribute)handlerAttributes[0]; } else { handlerAttribute = default; } foreach (var method in GrainType.GetMethods()) { var parameters = method.GetParameters(); if (parameters.Length >= 1 && typeof(IEvent).IsAssignableFrom(parameters[0].ParameterType)) { var evtType = parameters[0].ParameterType; if (parameters.Length == 2 && parameters[1].ParameterType == typeof(EventBase)) { var dynamicMethod = new DynamicMethod($"{evtType.Name}_handler", typeof(Task), new Type[] { typeof(object), typeof(IEvent), typeof(EventBase) }, GrainType, true); var ilGen = dynamicMethod.GetILGenerator();//IL生成器 ilGen.DeclareLocal(evtType); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Castclass, evtType); ilGen.Emit(OpCodes.Stloc_0); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldloc_0); ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Call, method); ilGen.Emit(OpCodes.Ret); var func = (Func <object, IEvent, EventBase, Task>)dynamicMethod.CreateDelegate(typeof(Func <object, IEvent, EventBase, Task>)); _handlerDict_1.Add(evtType, func); } else { var dynamicMethod = new DynamicMethod($"{evtType.Name}_handler", typeof(Task), new Type[] { typeof(object), typeof(IEvent) }, GrainType, true); var ilGen = dynamicMethod.GetILGenerator();//IL生成器 ilGen.DeclareLocal(evtType); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Castclass, evtType); ilGen.Emit(OpCodes.Stloc_0); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldloc_0); ilGen.Emit(OpCodes.Call, method); ilGen.Emit(OpCodes.Ret); var func = (Func <object, IEvent, Task>)dynamicMethod.CreateDelegate(typeof(Func <object, IEvent, Task>)); _handlerDict_0.Add(evtType, func); } } } }
public ObserverGrain() { GrainType = GetType(); handlerAttribute = grainIgnoreEventDict.GetOrAdd(GrainType, type => { var handlerAttributes = GrainType.GetCustomAttributes(typeof(IgnoreEventsAttribute), false); if (handlerAttributes.Length > 0) { return((IgnoreEventsAttribute)handlerAttributes[0]); } else { return(default); }
public ObserverGrain() { GrainType = GetType(); var handlerAttributes = GrainType.GetCustomAttributes(typeof(IgnoreEventsAttribute), false); if (handlerAttributes.Length > 0) { handlerAttribute = (IgnoreEventsAttribute)handlerAttributes[0]; } else { handlerAttribute = default; } var methods = GetType().GetMethods().Where(m => { var parameters = m.GetParameters(); return(parameters.Length >= 1 && parameters.Any(p => typeof(IEvent).IsAssignableFrom(p.ParameterType) && !p.ParameterType.IsInterface)); }).ToList(); var dynamicMethod = new DynamicMethod($"Handler_Invoke", typeof(Task), new Type[] { typeof(object), typeof(IEvent), typeof(EventBase) }, GrainType, true); var ilGen = dynamicMethod.GetILGenerator(); var switchMethods = new List <SwitchMethodEmit>(); for (int i = 0; i < methods.Count; i++) { var method = methods[i]; var methodParams = method.GetParameters(); var caseType = methodParams.Single(p => typeof(IEvent).IsAssignableFrom(p.ParameterType)).ParameterType; switchMethods.Add(new SwitchMethodEmit { Mehod = method, CaseType = caseType, DeclareLocal = ilGen.DeclareLocal(caseType), Lable = ilGen.DefineLabel(), Parameters = methodParams, Index = i }); } var sortList = new List <SwitchMethodEmit>(); foreach (var item in switchMethods.Where(m => !typeof(IEvent).IsAssignableFrom(m.CaseType.BaseType))) { sortList.Add(item); GetInheritor(item, switchMethods, sortList); } sortList.Reverse(); foreach (var item in switchMethods) { if (!sortList.Contains(item)) { sortList.Add(item); } } var defaultLabel = ilGen.DefineLabel(); var lastLable = ilGen.DefineLabel(); var declare_1 = ilGen.DeclareLocal(typeof(Task)); foreach (var item in sortList) { ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Isinst, item.CaseType); if (item.Index > 3) { if (item.DeclareLocal.LocalIndex > 0 && item.DeclareLocal.LocalIndex <= 255) { ilGen.Emit(OpCodes.Stloc_S, item.DeclareLocal); ilGen.Emit(OpCodes.Ldloc_S, item.DeclareLocal); } else { ilGen.Emit(OpCodes.Stloc, item.DeclareLocal); ilGen.Emit(OpCodes.Ldloc, item.DeclareLocal); } } else { if (item.Index == 0) { ilGen.Emit(OpCodes.Stloc_0); ilGen.Emit(OpCodes.Ldloc_0); } else if (item.Index == 1) { ilGen.Emit(OpCodes.Stloc_1); ilGen.Emit(OpCodes.Ldloc_1); } else if (item.Index == 2) { ilGen.Emit(OpCodes.Stloc_2); ilGen.Emit(OpCodes.Ldloc_2); } else { ilGen.Emit(OpCodes.Stloc_3); ilGen.Emit(OpCodes.Ldloc_3); } } ilGen.Emit(OpCodes.Brtrue, item.Lable); } ilGen.Emit(OpCodes.Br, defaultLabel); foreach (var item in sortList) { ilGen.MarkLabel(item.Lable); ilGen.Emit(OpCodes.Ldarg_0); //加载第一个参数 if (item.Parameters[0].ParameterType == item.CaseType) { LdEventArgs(item, ilGen); } else if (item.Parameters[0].ParameterType == typeof(EventBase)) { ilGen.Emit(OpCodes.Ldarg_2); } //加载第二个参数 if (item.Parameters.Length == 2) { if (item.Parameters[1].ParameterType == item.CaseType) { LdEventArgs(item, ilGen); } else if (item.Parameters[1].ParameterType == typeof(EventBase)) { ilGen.Emit(OpCodes.Ldarg_2); } } ilGen.Emit(OpCodes.Call, item.Mehod); if (item.DeclareLocal.LocalIndex > 0 && item.DeclareLocal.LocalIndex <= 255) { ilGen.Emit(OpCodes.Stloc_S, declare_1); } else { ilGen.Emit(OpCodes.Stloc, declare_1); } ilGen.Emit(OpCodes.Br, lastLable); } ilGen.MarkLabel(defaultLabel); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldarg_1); ilGen.Emit(OpCodes.Call, GrainType.GetMethod(nameof(DefaultHandler))); if (declare_1.LocalIndex > 0 && declare_1.LocalIndex <= 255) { ilGen.Emit(OpCodes.Stloc_S, declare_1); } else { ilGen.Emit(OpCodes.Stloc, declare_1); } ilGen.Emit(OpCodes.Br, lastLable); //last ilGen.MarkLabel(lastLable); if (declare_1.LocalIndex > 0 && declare_1.LocalIndex <= 255) { ilGen.Emit(OpCodes.Ldloc_S, declare_1); } else { ilGen.Emit(OpCodes.Ldloc, declare_1); } ilGen.Emit(OpCodes.Ret); handlerInvokeFunc = (Func <object, IEvent, EventBase, Task>)dynamicMethod.CreateDelegate(typeof(Func <object, IEvent, EventBase, Task>));