Добавление кода в начало / конец методов во время выполнения динамически - PullRequest
9 голосов
/ 17 марта 2010

Я знаю, что инструментарий - это метод динамического добавления кода трассировки в методы для включения трассировки и отладки.

Мне было интересно, если это только опция «Трассировка», жестко запрограммированная в CLR для добавления только кода трассировки, или есть возможность добавить какой-либо код в методы?

Например, я хочу проверять условие в начале каждого отдельного вызова метода в определенном классе (скажем, для разрешений). Могу ли я сделать это путем добавления динамического кода в начало методов во время выполнения?

Я не уверен, как работает эта «трассировка», но мне интересно, может ли это быть использовано и для других целей или нет.

Ответы [ 5 ]

4 голосов
/ 20 марта 2010

По сути, вам нужно написать CLR-профилировщик и использовать profiler API в c ++
Вам необходимо реализовать интерфейс ICorProfilerCallback.
То, что вы ищете, находится в обратном вызове JITCompilationStarted. Этот метод вызывается каждый раз, когда вызывается управляемый метод, и до того, как компилятор jit компилирует IL в машинный код. Любая работа по вставке кода во время выполнения должна выполняться в JITCompilationStarted.
Вы можете посмотреть, как это сделать, с помощью инструмента покрытия с открытым исходным кодом Part Cover .

3 голосов
/ 17 марта 2010

Вы имеете в виду Аспектно-ориентированное программирование (AOP).

Посмотрите на PostSharp .

Также: Аспектно-ориентированные фреймворки с открытым исходным кодом в C #

2 голосов
/ 17 марта 2010

Как уже отвечали другие, такие сквозные проблемы часто решаются с помощью Аспектно-ориентированного программирования (AOP).

Один из способов сделать AOP - это инструментарий кода с помощью таких инструментов, как PostSharp, но альтернатива, которая не требует дополнительных инструментов, - это использование Внедрение зависимостей (DI) и Decorator design шаблон.

Представьте, что ваш код использует интерфейс IFoo:

public interface IFoo
{
    string GetStuff(string request);
}

У вас может быть конкретная реализация MyFoo IFoo, но вы также можете написать один или несколько декораторов, которые обрабатывают различные аспекты:

public class AdministratorGuardingFoo : IFoo
{
    private readonly IFoo foo;

    public AdministratorGuardingFoo(IFoo foo)
    {
        if (foo == null)
        {
            throw new ArgumentNullException("foo");
        }

        this.foo = foo;
    }

    public string GetStuff(string request)
    {
        new PrincipalPermission(null, "Administrator").Demand();

        return this.foo.GetStuff(request);            
    }
}

Теперь вы можете (иметь свой DI-контейнер) завернуть MyFoo в AdministratorGuardingFoo. Все потребители, которые потребляют IFoo, не заметят разницы.

0 голосов
/ 17 марта 2010

CLR позволяет перехватывать методы через приемники сообщений.

0 голосов
/ 17 марта 2010

Я знаю PostSharp позволяет вам добавлять «аспекты» к существующим методам с помощью атрибуции, чтобы вы могли добавлять трассы входа / выхода в ваши методы

...