Как добавить атрибуты к методу во время выполнения?
Мы используем 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