Пример #1
0
 private void AttachEventHandler(EventInfo eventInfo, Func <DateTime> utcNow)
 {
     if (!recorderMap.TryGetValue(eventInfo.Name, out _))
     {
         var recorder = new EventRecorder(subject.Target, eventInfo.Name, utcNow);
         if (recorderMap.TryAdd(eventInfo.Name, recorder))
         {
             recorder.Attach(subject, eventInfo);
         }
     }
 }
Пример #2
0
        /// <summary>
        /// Obtains the <see cref="EventRecorder"/> for a particular event of the <paramref name="eventSource"/>.
        /// </summary>
        /// <param name="eventSource">The object for which to get an event recorder.</param>
        /// <param name="eventName">The name of the event.</param>
        /// <returns></returns>
        public static EventRecorder GetRecorderForEvent <T>(this T eventSource, string eventName)
        {
            EventRecorder eventRecorder = Map[eventSource].FirstOrDefault(r => r.EventName == eventName);

            if (eventRecorder == null)
            {
                string name = eventSource.GetType().Name;

                throw new InvalidOperationException(String.Format(
                                                        "Type <{0}> does not expose an event named \"{1}\".", name, eventName));
            }

            return(eventRecorder);
        }
        public void DeletingACounterShouldRaiseTheCollectionChangedEvent()
        {
            var dbfile = Path.Combine(RootPath, Guid.NewGuid().ToString("N") + ".db3");

            DatabaseHelper.CreateDatabase(dbfile);

            var db = new DatabaseHelper();
            var counter = new Counter
            {
                Name = "TestCounter",
                Description = "A test counter"
            };

            var res = Task.Run(async () =>
            {
                await db.AddOrUpdateCounterAsync(counter);
                return 0;
            }).Result;

            var eventRecorder = new EventRecorder(db, nameof(DatabaseHelper.CountersChanged));
            eventRecorder.RecordEvent();
            
            res = Task.Run(async () =>
            {
                await db.DeleteCounterAsync(counter);
                return 0;
            }).Result;

            eventRecorder.Should().HaveCount(1);
        }
Пример #4
0
        /// <summary>
        /// Generates an eventhandler for an event of type eventSignature that calls RegisterEvent on recorder
        /// when invoked.
        /// </summary>
        public static Delegate GenerateHandler(Type eventSignature, EventRecorder recorder)
        {
            Type returnType = GetDelegateReturnType(eventSignature);

            Type[] parameters = GetDelegateParameterTypes(eventSignature);

            Module module = recorder.GetType()
                            .Module;

            var eventHandler = new DynamicMethod(
                eventSignature.Name + "DynamicHandler",
                returnType,
                AppendParameterListThisReference(parameters),
                module);

            MethodInfo methodToCall = typeof(EventRecorder).GetMethod(nameof(EventRecorder.RecordEvent),
                                                                      BindingFlags.Instance | BindingFlags.Public);

            ILGenerator ilGen = eventHandler.GetILGenerator();

            // Make room for the one and only local variable in our function
            ilGen.DeclareLocal(typeof(object[]));

            // Create the object array for the parameters and store in local var index 0
            ilGen.Emit(OpCodes.Ldc_I4, parameters.Length);
            ilGen.Emit(OpCodes.Newarr, typeof(object));
            ilGen.Emit(OpCodes.Stloc_0);

            for (var index = 0; index < parameters.Length; index++)
            {
                // Push the object array onto the evaluation stack
                ilGen.Emit(OpCodes.Ldloc_0);

                // Push the array index to store our parameter in onto the evaluation stack
                ilGen.Emit(OpCodes.Ldc_I4, index);

                // Load the parameter
                ilGen.Emit(OpCodes.Ldarg, index + 1);

                // Box value-type parameters
                if (parameters[index].IsValueType)
                {
                    ilGen.Emit(OpCodes.Box, parameters[index]);
                }

                // Store the parameter in the object array
                ilGen.Emit(OpCodes.Stelem_Ref);
            }

            // Push the this-reference on the stack as param 0 for calling the handler
            ilGen.Emit(OpCodes.Ldarg_0);

            // Push the object array onto the stack as param 1 for calling the handler
            ilGen.Emit(OpCodes.Ldloc_0);

            // Call the handler
            ilGen.EmitCall(OpCodes.Callvirt, methodToCall, null);

            ilGen.Emit(OpCodes.Ret);

            return(eventHandler.CreateDelegate(eventSignature, recorder));
        }