Как добавить атрибуты к методу во время выполнения?

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

Как добавить атрибуты к методу во время выполнения?

Ответы

Ответ 1

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

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

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

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

Удачи!

Ответ 2

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

Ответ 3

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

Ответ 4

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