Exemple #1
0
 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);
         }
Exemple #2
0
        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>));
Exemple #3
0
        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>));
Exemple #4
0
        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();