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

时间:2008-11-06 12:03:37

标签: c# reflection attributes reflection.emit

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

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

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

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

然后将对象传递给一个匹配所有内容的EventInspector。

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

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

4 个答案:

答案 0 :(得分:9)

你想要实现的目标非常复杂,所以我会尝试提供一些东西,以帮助你入门。这就是我认为你需要结合才能实现某些目标:

  1. 使用方法AbstractEventDebugger定义抽象类Search,该方法搜索所有event成员,并使用EventInspector注册它们。另外,定义一个方法IdentifyEvent,它允许您识别调用它的事件(这取决于您 - 具有哪些参数等)。
  2. 使用dynamic type(如所述here)定义TypeBuilder,继承自您的班级。此类将是您的debugger对象的类。
  3. 使用Reflection.Emit.MethodBuilder(请参阅here)将处理程序附加到您的班级,这将从父班调用IdentifyEvent方法,
  4. Reflection.Emit使用CustomAttributeBuilder类处理程序的属性(请参阅here)。
  5. 创建dynamic类的实例并将其发送到EventInspector。
  6. 点燃:)
  7. Here是一个关于如何创建一个调用某个东西的方法的示例(实际上它是经典的“Hello world”)。

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

    祝你好运!

答案 1 :(得分:3)

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

答案 2 :(得分:1)

你需要钻研DynamicMethod的世界。但是,当你需要了解MSIL时,我真的建议你仔细考虑你的架构。

答案 3 :(得分:1)

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

的TraceSource

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调试窗口,你有很多选择。我建议查看以下文章:

Code Instrumentation with TraceSource My Persoanl Vade Mecum