c# .net mocking moles isolation-frameworks

c# - ¿Cómo se implementa el marco de aislamiento de lunares?



.net mocking (2)

Esto funciona como envoltorio para cualquier ensamblaje que desee, por ejemplo, mscorlib (este ejemplo se basa en Moles Assembly Wrapper of mscorlib ). Esto le da poder para reemplazar cualquier método .NET por el delegado escrito por el codificador .

Esto no está funcionando automáticamente. Primero debe crear antes de que este inicio funcione, el archivo de configuración XML de Moles con la lista de ensamblajes a "Wrapper" y con este código, los lunares generan una referencia de este conjunto desde el archivo de configuración. Y debe agregar en este archivo using namespace System.Moles , y antes de la función [HostType("Moles")]

Moles es un marco de aislamiento creado por Microsoft. Una característica interesante de Moles es que puede "simular" métodos estáticos / no virtuales y clases selladas (lo que no es posible con marcos como Moq). A continuación se muestra la demostración rápida de lo que pueden hacer los topos:

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);

Parece que Moles puede modificar el cuerpo de CIL de cosas como DateTime.Now en tiempo de ejecución. Como Moles no es de código abierto, tengo curiosidad por saber qué mecanismo usa Moles para modificar los CIL de los métodos en tiempo de ejecución. ¿Alguien puede arrojar algo de luz?


Moles implementa un generador de perfiles CLR (en particular, la interfaz ICorProfilerCallback ) que permite reescribir los cuerpos del método MSIL antes de que sean compilados en código de ensamblado por el tiempo de ejecución de .NET. Esto se hace en particular a través de la JitCompileStarted llamada JitCompileStarted .

En cada método, Moles introduce un desvío que se ve así:

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 } } }

Cuando configura un topo, su delegado se almacena en el __Detours diccionario subyacente que se busca cuando se ejecuta el método.