14

我们使用 Microsoft.Practices.CompositeUI.EventBroker 在我们的应用程序中处理事件订阅和发布。可行的方法是向事件添加一个属性,指定一个主题名称,如下所示:

[EventPublication("example", PublicationScope.Global)]
public event EventHandler Example;

然后向处理程序添加另一个属性,具有相同的主题名称,如下所示:

[EventSubscription("example", ThreadOption.Publisher)]
public void OnExample(object sender, EventArgs e)
{
    ...
}

然后你将你的对象传递给一个匹配所有东西的 EventInspector。

我们需要对此进行调试,因此我们正在尝试创建一个订阅所有事件的调试类。我可以获得所有主题名称的列表......但仅限于运行时。因此,在将调试对象传递给 EventInspector 之前,我需要能够在运行时向方法添加属性。

如何在运行时向方法添加属性?

4

4 回答 4

11

您要实现的目标非常复杂,因此我将尝试提供一些东西来帮助您入门。这就是我认为你需要结合起来才能实现的目标:

  1. 定义一个抽象类AbstractEventDebugger,使用Search搜索所有event成员的方法,并将它们注册到 EventInspector。此外,定义一个方法IdentifyEvent,允许您识别调用它的事件(这取决于您 - 将具有哪些参数等)。
  2. 定义一个继承自您的类的dynamic typeusing TypeBuilder(如此处所述)。此类将是您的debugger对象的类。
  3. Reflection.Emit.MethodBuilder使用(参见此处)将处理程序附加到您的类,这将从IdentifyEvent父类调用方法,并且,
  4. Reflection.Emit使用CustomAttributeBuilder类的处理程序上的属性(请参见此处)。
  5. 创建您的dynamic类的实例并将其发送到 EventInspector。
  6. 燃烧起来;动起来:)

是一个关于如何创建调用某物的方法的示例(实际上它是经典的“Hello world”)。

你需要做很多调整才能把它做好,但你会学到很多关于反射的知识。

祝你好运!

于 2008-11-06T12:52:30.617 回答
3

属性是一个编译时特性(除非您正在处理 ComponentModel - 但我怀疑它正在使用反射)。因此,您不能在运行时添加属性。这将是一个类似于“如何在运行时向类型添加额外的方法?”的问题。在常规 C#/.NET(DLR 之前)中,您不能。

于 2008-11-06T12:21:59.507 回答
1

您需要深入了解DynamicMethod. 但是,由于您需要了解 MSIL,我真的建议您认真考虑您的架构。

于 2008-11-06T12:24:46.613 回答
1

EventInspector 使用 EventTopics(存储在 WorkItem 中)来完成所有繁重的工作。每个 EventTopic 对象都可以访问一个名为

Microsoft.Practices.CompositeUI.EventBroker.EventTopic

您可以在 app.config 文件中启用,如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.diagnostics>
        <switches>
            <add name="Microsoft.Practices.CompositeUI.EventBroker.EventTopic" value="All" />
        </switches>
    </system.diagnostics>
</configuration>

这应该会使大量有用的消息路由到 Visual Studio 中的调试窗口。如果你想超越 VS 调试窗口,你有很多选择。我建议查看以下文章:

使用 TraceSource 进行代码检测 My Persoanl Vade Mecum

于 2008-11-06T13:43:35.940 回答