Как реализована среда Moles Isolation? - PullRequest
22 голосов
/ 11 июня 2010

Родинок - это изолирующая структура, созданная Microsoft. Отличная особенность Moles заключается в том, что он может «высмеивать» статические / не виртуальные методы и запечатанные классы (что невозможно в таких средах, как Moq). Ниже приведена краткая демонстрация того, что могут делать кроты:

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

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

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

Ответы [ 2 ]

49 голосов
/ 18 июня 2010

Moles реализует профилировщик CLR (в частности, интерфейс ICorProfilerCallback ), который позволяет переписывать тела методов MSIL до того, как они будут скомпилированы в код сборки средой выполнения .NET. Это делается, в частности, с помощью обратного вызова 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, который просматривается при каждом выполнении метода.

0 голосов
/ 11 июня 2010

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

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

...