22

Moles是微软创建的隔离框架。Moles 的一个很酷的特性是它可以“模拟”静态/非虚拟方法和密封类(这在像 Moq 这样的框架中是不可能的)。下面是 Moles 可以做什么的快速演示:

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 能够DateTime.Now在运行时修改 CIL 主体。由于 Moles 不是开源的,我很想知道 Moles 使用哪种机制来在运行时修改方法的 CIL。任何人都可以解释一下吗?

4

2 回答 2

49

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

当你设置一个mole时,你的委托存储在底层的__Detours字典中,每当方法执行时都会被查找。

于 2010-06-18T08:42:35.773 回答
0

例如,这就像您想要的任何程序集的包装器一样工作mscorlib(此示例基于 Moles Assembly Wrapper of mscorlib)。这使您能够通过 coder 编写的委托替换任何 .NET 方法

这不是自动工作的。在此开始工作之前,您必须首先创建Moles XML 配置文件,其中包含“包装器”的程序集列表,并通过此代码 Moles 从配置文件生成此程序集的引用。并且您必须在此文件中添加using namespace System.Moles, 和之前的功能[HostType("Moles")]

于 2010-06-11T09:56:45.910 回答