Подтвердить что ты не робот

Как реализована структура изоляции Moles?

Moles - это среда изоляции, созданная Microsoft. Замечательная особенность Moles заключается в том, что он может "высмеять" статические/не виртуальные методы и запечатанные классы (что невозможно в рамках таких фреймворков, как Moq). Ниже приведена краткая демонстрация того, что может сделать Моулс:

Assert.AreNotEqual(new DateTime(2012, 1, 1), DateTime.Now);

// MDateTime is part of Moles; the below will "override" DateTime.Now behavior
MDateTime.NowGet = () => new DateTime(2012, 1, 1); 
Assert.AreEqual(new DateTime(2012, 1, 1), DateTime.Now);

Похоже, Moles может модифицировать тело CIL, например, DateTime.Now во время выполнения. Поскольку Moles не является открытым исходным кодом, мне любопытно узнать, какой механизм использует Moles, чтобы модифицировать методы CIL во время выполнения. Может ли кто-нибудь пролить свет?

4b9b3361

Ответ 1

Moles реализует профилировщик CLR (в частности, интерфейс ICorProfilerCallback), который позволяет переписывать тела метода MSIL, прежде чем они будут скомпилированы в код сборки с помощью .NET runtime. Это делается, в частности, через обратный вызов JitCompileStarted.

В каждом методе Moles вводит обход, который выглядит следующим образом:

static struct DateTime 
{
    static DateTime Now
    {
        get 
        {
            Func<DateTime> d = __Detours.GetDelegate(
                null, // this point null in static methods
                methodof(here) // current method token
                );
            if(d != null)
                return d();
            ... // original body
        }
    }
}

Когда вы устанавливаете родинку, ваш делегат хранится в базовом словаре __Detours, который проверяется, когда этот метод выполняется.

Ответ 2

Это работает как оболочка для любой сборки, которую вы хотите, например mscorlib (этот пример основан на Moles Assembly Wrapper mscorlib). Это дает вам возможность заменить любой .NET-метод делегатом, написанным coder.

Это не работает автоматически. Сначала вы должны создать до начала этого запуска, конфигурационный файл Moles XML со списком сборок в "Wrapper" и по этому коду Moles генерирует ссылки на эти сборки из файла конфигурации. И вы должны в этом файле добавить using namespace System.Moles, а перед функцией [HostType("Moles")]