Как добавить атрибуты к методу во время выполнения? - PullRequest
13 голосов
/ 06 ноября 2008

Мы используем 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 ]

9 голосов
/ 06 ноября 2008

То, что вы пытаетесь достичь, довольно сложно, поэтому я постараюсь предоставить что-то, только чтобы вы начали. Вот что я думаю, вам нужно объединить, чтобы чего-то добиться:

  1. Определите абстрактный класс AbstractEventDebugger с помощью метода Search, который ищет все члены event и регистрирует их с помощью EventInspector. Также определите метод IdentifyEvent, который позволит вам определить событие, которое его вызвало (это зависит от вас - какие параметры будут иметь и т. Д.).
  2. Определите dynamic type, используя TypeBuilder (как описано здесь ), который наследуется от вашего класса. Этот класс будет классом вашего debugger объекта.
  3. Присоедините обработчики к вашему классу, используя Reflection.Emit.MethodBuilder (см. здесь ), который будет вызывать метод IdentifyEvent из родительского класса и,
  4. Reflection.Emit атрибуты в обработчиках, использующие класс CustomAttributeBuilder (см. здесь ).
  5. Создайте экземпляр вашего dynamic класса и отправьте его в EventInspector.
  6. Запустите его :)

Здесь - пример того, как создать метод, который вызывает что-то (на самом деле это классический «Hello world»).

Вам нужно будет сделать много настроек, чтобы сделать это хорошо, но вы многое узнаете о рефлексии.

Удачи!

3 голосов
/ 06 ноября 2008

Атрибуты являются функцией времени компиляции (если вы не имеете дело с ComponentModel - но я подозреваю, что он использует отражение). Таким образом, вы не можете добавлять атрибуты во время выполнения. Это было бы похоже на вопрос «как добавить дополнительный метод к типу во время выполнения?». В обычном C # / .NET (до DLR) вы не можете.

1 голос
/ 06 ноября 2008

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, у вас есть много вариантов. Я бы порекомендовал проверить следующую статью:

Инструментарий кода с TraceSource My Persoanl Vade Mecum

1 голос
/ 06 ноября 2008

Вам необходимо окунуться в мир DynamicMethod. Однако, поскольку вам нужно знать MSIL, я действительно советую вам серьезно подумать о своей архитектуре.

...