挂载非引用Assembly中的事件

简介: 有两个 Assembly A,B 在A中声明了一个事件(某个类中的某个事件), B没有引用这Assembly ,但是想挂A中的这个事件。当A中的某个逻辑fire这个Event时,B挂事件的地方要(B的handler)要做些事情。

有两个 Assembly A,B 在A中声明了一个事件(某个类中的某个事件), B没有引用这Assembly ,但是想挂A中的这个事件。当A中的某个逻辑fire这个Event时,B挂事件的地方要(B的handler)要做些事情。

FireFarEvent 是 Assembly A, MainForm 类公开一个 SomeEvent 事件, FireEvent button 会 Fire 这个 Event.

AttachFarEvent 是 Assembly B, AttachFarEventForm 中 btnAttachEvent_Click 会 hook FireFarEvent 中的 SomeEvent.

 

AttachFarEvent代码如下:

 

        private void btnAttachEvent_Click(object sender, EventArgs e)
        {
            if(assembly == null || fireEventForm == null)
            {
                MessageBox.Show("Please click the first button to load the fire event form.");
                return;
            }
            Type fireFarEventFormType = fireEventForm.GetType();
            farEventEventInfo = fireFarEventFormType.GetEvent("SomeEvent");

            EventHandler tempHandler = new EventHandler(this.farEventHandler); // for dynamic method.
            MethodInfo tempHandlerMethodInfo = tempHandler.Method;


            DynamicMethod dynamicMethod = new DynamicMethod(
                "BridgeMethodForAttachEvent", typeof(void),
                new Type[] { typeof(object), assembly.GetType("FireFarEvent.FarEventArgs") },
                this.GetType());

            ILGenerator il = dynamicMethod.GetILGenerator();

            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Call, tempHandlerMethodInfo);
            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ret);

            dynamicMethod.DefineParameter(1, ParameterAttributes.In, "object");
            dynamicMethod.DefineParameter(2, ParameterAttributes.In, "e");

            farEventDelegate = dynamicMethod.CreateDelegate(farEventEventInfo.EventHandlerType);
            farEventEventInfo.AddEventHandler(fireEventForm, farEventDelegate);
        }

 

 

DetachFarEvent代码如下:

 

 

        private void btnDetachEvent_Click(object sender, EventArgs e)
        {
            if (assembly == null || fireEventForm == null || farEventEventInfo == null)
            {
                MessageBox.Show("Please click the first button to load the fire event form.");
                return;
            }
            farEventEventInfo.RemoveEventHandler(fireEventForm, farEventDelegate);
        }

 

 

img_2e6c74bf896a012f8023154060b60f32.gif

 

 

Demo下载:AttachFarEvent.rar

相关文章
|
7月前
|
C++
Qt定义属性类信息报错‘Qstring‘ was not declared in this scope; did you mean ‘xxx‘?并且还有有一堆报错,问题还出现在moc文件
Qt定义属性类信息报错‘Qstring‘ was not declared in this scope; did you mean ‘xxx‘?并且还有有一堆报错,问题还出现在moc文件
109 0
|
Windows
命名空间“System”中不存在类型或命名空间名称“Windows”(是缺少程序集引用吗?)
命名空间“System”中不存在类型或命名空间名称“Windows”(是缺少程序集引用吗?)
命名空间“System”中不存在类型或命名空间名称“Windows”(是缺少程序集引用吗?)
|
C#
在编写wpf界面时候中出现如下错误: 类型引用不明确。至少有两个名称空间(“System.Windows”和“System.Windows”)中已出现名为“VisualStateManager”的类型。请考虑调整程序集 XmlnsDefinition 特性。
原文:在编写wpf界面时候中出现如下错误: 类型引用不明确。至少有两个名称空间(“System.Windows”和“System.Windows”)中已出现名为“VisualStateManager”的类型。
1002 0
从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法
原文:从加载DLL的中获取放置于Resources文件夹中资源字典的几种方法 主程序 为 Main_Test.exe 被加载的DLL 为 Load_Test.dll  此DLL 中 有一个 文件夹Resources文件夹有一个资源字典Graphics.
1333 0
|
程序员
错误:“ResourceDictionary”根元素需要 x:Class 特性来支持 XAML 文件中的事件处理程序。请移除 MouseLeftButtonDown 事件的事件处理程序.
原文:错误:“ResourceDictionary”根元素需要 x:Class 特性来支持 XAML 文件中的事件处理程序。请移除 MouseLeftButtonDown 事件的事件处理程序. 转载于(https://social.
2373 0