views:

1999

answers:

4

We're using Microsoft.Practices.CompositeUI.EventBroker to handle event subscription and publication in our application. The way that works is that you add an attribute to your event, specifying a topic name, like this:

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

then you add another attribute to your handler, with the same topic name, like this:

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

Then you pass your objects to an EventInspector which matches everything up.

We need to debug this, so we're trying to create a debug class that subscribes to all the events. I can get a list of all the topic names... but only at runtime. So I need to be able to add attributes to a method at runtime, before we pass our debug object to the EventInspector.

How do I add attributes to a method at runtime?

+2  A: 

Attributes are a compile-time feature (unless you are dealing with ComponentModel - but I suspect it is using reflection). As such, you cannot add attributes at runtime. It would a similar question to "how do I add an extra method to a type at runtime?". In regular C# / .NET (pre-DLR), you can't.

Marc Gravell
Actually, it can be done by mixing Dynamic Assemblies and normal assemblies. .NET 2.0 Has support for them, and you don't need to use DLR just for this.
Bogdan Maxim
@Bogdan - but that still doesn't allow you to add attributes to an existing type/member.
Marc Gravell
+1  A: 

You need to delve into the world of the DynamicMethod. However, as you need then to know MSIL, I really suggest you think hard about your architecture.

David Kemp
Maybe his architecture is dynamic, aiming to provide services to multiple types, at runtime. It's not uncommon, and it is actually recommended if you want to have a modular system.
Bogdan Maxim
+3  A: 

What you are trying to achieve is quite complicated, so I will try to provide something just to get you started. This is what I think you would need to combine in order to achieve something:

  1. Define an abstract class AbstractEventDebugger, with a method Search that searches all of the event members, and registers them with the EventInspector. Also, define a method IdentifyEvent that will allow you to identify the event that has called it (this depends on you - what parameters will have, etc.).
  2. Define a dynamic type using TypeBuilder (as described here), that inherits from your class. This class would be the class of your debugger object.
  3. Attach the Handlers to your class using Reflection.Emit.MethodBuilder (see here), which will be calling the IdentifyEvent method from the parent class and,
  4. Reflection.Emit the attributes on the handlers using CustomAttributeBuilder class (see here).
  5. Create an instance of your dynamic class and send it to the EventInspector.
  6. Fire it up :)

Here is a sample on how to create a method that calls something (Actually it's the classic "Hello world").

You will need to do a lot of tweaking in order to get it done well, but you will learn a lot about reflection.

Good luck!

Bogdan Maxim
+1  A: 

The EventInspector uses EventTopics (which are stored in the WorkItem) to do all the heavy lifting. Each EventTopic object has access to a TraceSource called

Microsoft.Practices.CompositeUI.EventBroker.EventTopic

Which you can enable in your app.config file like this:

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

This should make plenty of useful messages get routed to your debug window in Visual Studio. If you want to go beyond the VS debug window you have plenty of options. I'd recommend checking out the following article:

Code Instrumentation with TraceSource My Persoanl Vade Mecum

Wolfbyte