挂载非引用Assembly中的事件

有两个 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代码如下:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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代码如下:

 

 

1
2
3
4
5
6
7
8
9
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);
}

 

 

 

 

Demo下载:AttachFarEvent.rar

posted @   葡萄城技术团队  阅读(3187)  评论(12编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示