mirror of
				https://github.com/esiur/esiur-dotnet.git
				synced 2025-10-30 23:51:34 +00:00 
			
		
		
		
	DynamicMethod Nullable Events
This commit is contained in:
		| @@ -15,6 +15,7 @@ using Esiur.Proxy; | ||||
| using Esiur.Core; | ||||
| using System.Text.Json; | ||||
| using System.ComponentModel.DataAnnotations.Schema; | ||||
| using System.Reflection.Emit; | ||||
|  | ||||
| namespace Esiur.Resource; | ||||
|  | ||||
| @@ -607,6 +608,27 @@ public class Instance | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     internal void EmitResourceEventByIndex(byte eventIndex, object value) | ||||
|     { | ||||
|         IResource res; | ||||
|         if (this.resource.TryGetTarget(out res)) | ||||
|         { | ||||
|             var eventTemplate = template.GetEventTemplateByIndex(eventIndex); | ||||
|             EventOccurred?.Invoke(new EventOccurredInfo(res, eventTemplate, value)); | ||||
|         } | ||||
|     }     | ||||
|      | ||||
|     internal void EmitCustomResourceEventByIndex(object issuer, Func<Session, bool> receivers, byte eventIndex, object value) | ||||
|     { | ||||
|         IResource res; | ||||
|         if (this.resource.TryGetTarget(out res)) | ||||
|         { | ||||
|             var eventTemplate = template.GetEventTemplateByIndex(eventIndex); | ||||
|             CustomEventOccurred?.Invoke(new CustomEventOccurredInfo(res, eventTemplate, receivers, issuer, value)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Get the value of a given property by name. | ||||
|     /// </summary> | ||||
| @@ -844,6 +866,13 @@ public class Instance | ||||
|     /// </summary> | ||||
|     public AutoList<IPermissionsManager, Instance> Managers => managers; | ||||
|  | ||||
|  | ||||
|     public void CallMeTest(Instance ins, int? val) => | ||||
|         ins.EmitResourceEventByIndex(201, val); | ||||
|  | ||||
|     public void CallMeTest2(Instance instance, object issuer, Func<Session, bool> receivers, int? val) => | ||||
|         instance.EmitCustomResourceEventByIndex(issuer, receivers, 201, val); | ||||
|  | ||||
|     /// <summary> | ||||
|     /// Create new instance. | ||||
|     /// </summary> | ||||
| @@ -893,10 +922,11 @@ public class Instance | ||||
| #endif | ||||
|  | ||||
|  | ||||
|         var emitEventByIndexMethod = GetType().GetMethod("EmitResourceEventByIndex", BindingFlags.Instance | BindingFlags.NonPublic); | ||||
|         var emitCustomEventByIndexMethod = GetType().GetMethod("EmitCustomResourceEventByIndex", BindingFlags.Instance | BindingFlags.NonPublic); | ||||
|  | ||||
|         foreach (var evt in template.Events) | ||||
|         { | ||||
|             //if (evt.EventHandlerType != typeof(ResourceEventHandler)) | ||||
|             //    continue; | ||||
|  | ||||
|             if (evt.EventInfo == null) | ||||
|                 continue; | ||||
| @@ -906,21 +936,51 @@ public class Instance | ||||
|             if (eventGenericType == typeof(ResourceEventHandler<>)) | ||||
|             { | ||||
|  | ||||
|                 // var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true); | ||||
|                 // if (ca.Length == 0) | ||||
|                 //     continue; | ||||
|                 var dm = new DynamicMethod("_", null, | ||||
|                    new Type[] {typeof(Instance), evt.EventInfo.EventHandlerType.GenericTypeArguments[0] },  | ||||
|                    typeof(Instance).Module, true); | ||||
|  | ||||
|                 ResourceEventHandler<object> proxyDelegate = (args) => EmitResourceEvent(evt, args); | ||||
|  | ||||
|                 var il = dm.GetILGenerator(); | ||||
|                 il.Emit(OpCodes.Ldarg_0); | ||||
|                 il.Emit(OpCodes.Ldc_I4, (int)evt.Index); | ||||
|                 il.Emit(OpCodes.Ldarg_1); | ||||
|                 il.Emit(OpCodes.Box, evt.EventInfo.EventHandlerType.GenericTypeArguments[0]); | ||||
|                 il.Emit(OpCodes.Callvirt, emitEventByIndexMethod); | ||||
|                 il.Emit(OpCodes.Nop); | ||||
|                 il.Emit(OpCodes.Ret); | ||||
|  | ||||
|  | ||||
|                 var proxyDelegate= dm.CreateDelegate(evt.EventInfo.EventHandlerType, this); | ||||
|  | ||||
|                 //ResourceEventHandler<object> proxyDelegate = new ResourceEventHandler<object>((args) => EmitResourceEvent(evt, args)); | ||||
|                 evt.EventInfo.AddEventHandler(resource, proxyDelegate); | ||||
|  | ||||
|  | ||||
|             } | ||||
|             else if (eventGenericType == typeof(CustomResourceEventHandler<>)) | ||||
|             { | ||||
|                 //var ca = (ResourceEvent[])evt.GetCustomAttributes(typeof(ResourceEvent), true); | ||||
|                 //if (ca.Length == 0) | ||||
|                 //    continue; | ||||
|                 var dm = new DynamicMethod("_", null, | ||||
|                    new Type[] { typeof(Instance), typeof(object), typeof(Func<Session, bool>), | ||||
|                        evt.EventInfo.EventHandlerType.GenericTypeArguments[0] }, | ||||
|                    typeof(Instance).Module, true); | ||||
|  | ||||
|                 CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt, args); | ||||
|  | ||||
|                 var il = dm.GetILGenerator(); | ||||
|                 il.Emit(OpCodes.Ldarg_0); | ||||
|                 il.Emit(OpCodes.Ldarg_1); | ||||
|                 il.Emit(OpCodes.Ldarg_2); | ||||
|                 il.Emit(OpCodes.Ldc_I4, (int)evt.Index); | ||||
|                 il.Emit(OpCodes.Ldarg_3); | ||||
|                 il.Emit(OpCodes.Box, evt.EventInfo.EventHandlerType.GenericTypeArguments[0]); | ||||
|                 il.Emit(OpCodes.Callvirt, emitCustomEventByIndexMethod); | ||||
|                 il.Emit(OpCodes.Nop); | ||||
|                 il.Emit(OpCodes.Ret); | ||||
|  | ||||
|  | ||||
|                 var proxyDelegate = dm.CreateDelegate(evt.EventInfo.EventHandlerType, this); | ||||
|  | ||||
|                 //CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt, args); | ||||
|                 evt.EventInfo.AddEventHandler(resource, proxyDelegate); | ||||
|             } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user