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 SnapshotHandler() { var thisType = GetType(); var handlerAttributes = thisType.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 >= 2 && parameters.Any(p => p.ParameterType == typeof(Snapshot)) && parameters.Any(p => typeof(IEvent).IsAssignableFrom(p.ParameterType))); }).ToList(); var dynamicMethod = new DynamicMethod($"Handler_Invoke", typeof(void), new Type[] { typeof(object), typeof(Snapshot), typeof(IEvent), typeof(EventBase) }, thisType, true); var ilGen = dynamicMethod.GetILGenerator(); var items = 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; items.Add(new SwitchMethodEmit { Mehod = method, CaseType = caseType, DeclareLocal = ilGen.DeclareLocal(caseType), Lable = ilGen.DefineLabel(), Parameters = methodParams, Index = i }); } var defaultLabel = ilGen.DefineLabel(); foreach (var item in items) { ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Isinst, item.CaseType); if (item.Index > 3) { ilGen.Emit(OpCodes.Stloc_S, item.DeclareLocal); ilGen.Emit(OpCodes.Ldloc_S, 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_S, item.Lable); } ilGen.Emit(OpCodes.Br_S, defaultLabel); foreach (var item in items) { ilGen.MarkLabel(item.Lable); ilGen.Emit(OpCodes.Ldarg_0); //加载第一个参数 if (item.Parameters[0].ParameterType == typeof(Snapshot)) { ilGen.Emit(OpCodes.Ldarg_1); } else if (item.Parameters[0].ParameterType == typeof(EventBase)) { ilGen.Emit(OpCodes.Ldarg_3); } else { LdEventArgs(item, ilGen); } //加载第二个参数 if (item.Parameters[1].ParameterType == typeof(Snapshot)) { ilGen.Emit(OpCodes.Ldarg_1); } else if (item.Parameters[1].ParameterType == typeof(EventBase)) { ilGen.Emit(OpCodes.Ldarg_3); } else { LdEventArgs(item, ilGen); } //加载第三个参数 if (item.Parameters.Length == 3) { if (item.Parameters[1].ParameterType == typeof(Snapshot)) { ilGen.Emit(OpCodes.Ldarg_1); } else if (item.Parameters[1].ParameterType == typeof(EventBase)) { ilGen.Emit(OpCodes.Ldarg_3); } else { LdEventArgs(item, ilGen); } } ilGen.Emit(OpCodes.Call, item.Mehod); ilGen.Emit(OpCodes.Ret); } ilGen.MarkLabel(defaultLabel); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Call, thisType.GetMethod(nameof(DefaultHandler))); ilGen.Emit(OpCodes.Ret); handlerInvokeFunc = (Action <object, Snapshot, IEvent, EventBase>)dynamicMethod.CreateDelegate(typeof(Action <object, Snapshot, IEvent, EventBase>));
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>));
public SnapshotHandler() { var thisType = GetType(); var handlerAttributes = thisType.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 >= 2 && parameters.Any(p => p.ParameterType == typeof(Snapshot)) && parameters.Any(p => typeof(IEvent).IsAssignableFrom(p.ParameterType) && !p.ParameterType.IsInterface)); }).ToList(); var dynamicMethod = new DynamicMethod($"Handler_Invoke", typeof(void), new Type[] { typeof(object), typeof(Snapshot), typeof(IEvent), typeof(EventBase) }, thisType, 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(); foreach (var item in sortList) { ilGen.Emit(OpCodes.Ldarg_2); 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 == typeof(Snapshot)) { ilGen.Emit(OpCodes.Ldarg_1); } else if (item.Parameters[0].ParameterType == typeof(EventBase)) { ilGen.Emit(OpCodes.Ldarg_3); } else { LdEventArgs(item, ilGen); } //加载第二个参数 if (item.Parameters[1].ParameterType == typeof(Snapshot)) { ilGen.Emit(OpCodes.Ldarg_1); } else if (item.Parameters[1].ParameterType == typeof(EventBase)) { ilGen.Emit(OpCodes.Ldarg_3); } else { LdEventArgs(item, ilGen); } //加载第三个参数 if (item.Parameters.Length == 3) { if (item.Parameters[1].ParameterType == typeof(Snapshot)) { ilGen.Emit(OpCodes.Ldarg_1); } else if (item.Parameters[1].ParameterType == typeof(EventBase)) { ilGen.Emit(OpCodes.Ldarg_3); } else { LdEventArgs(item, ilGen); } } ilGen.Emit(OpCodes.Call, item.Mehod); ilGen.Emit(OpCodes.Ret); } ilGen.MarkLabel(defaultLabel); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldarg_2); ilGen.Emit(OpCodes.Call, thisType.GetMethod(nameof(DefaultHandler))); ilGen.Emit(OpCodes.Ret); var parames = new ParameterExpression[] { Expression.Parameter(typeof(object)), Expression.Parameter(typeof(Snapshot)), Expression.Parameter(typeof(IEvent)), Expression.Parameter(typeof(EventBase)) }; var body = Expression.Call(dynamicMethod, parames); handlerInvokeFunc = Expression.Lambda <Action <object, Snapshot, IEvent, EventBase> >(body, parames).Compile();