Moles隔离框架是如何实现的?

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 不是开源的,我想知道它使用哪种机制来在运行时修改方法的 CIL。有人能够详细解释一下吗?


4
我强烈推荐观看@Peli解释Pex和Moles的这三个视频。它们非常好! 视频第一部分,视频第二部分,视频第三部分。 - Mike Christian
3个回答

50
Moles实现了一个CLR分析器(特别是ICorProfilerCallback接口),可以在.NET运行时将MSIL方法体重写为汇编代码之前进行。这是通过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字典中,每当方法被执行时都会进行查找。

4
+1 是为了真正解释它是如何工作的。我也很好奇。很高兴知道在调试模式下确实有一种重写方法的方式 ;) - TomTom
我也点赞了 - 我一直在想他们是怎么做到的,然后偶然发现了这个 - 这也很有道理。 - Shaun Wilde
1
我强烈推荐观看@Peli的这三个视频,他在其中解释了Pex和Moles的工作原理。它们非常好!视频第1部分; 视频第2部分; 视频第3部分 - Mike Christian

0

这个工具可以作为任何程序集的包装器,例如 mscorlib(这个例子基于 Moles Assembly Wrapper of mscorlib)。这使您有能力通过编写委托来替换任何 .NET 方法。

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


0

有一份名为“Moles: Tool-Assisted Environment Isolation With Closures”的演示文稿。请注意结尾处的“WITH CLOSURES”。它是在2010年编写的。其中一位作者是Jonathan de Halleux。我会假设这是Peli de Halleux的正式名字。这篇论文可以在书籍《Objects, Models, Components, Patterns: 48th International Conference, TOOLS 2010, Málaga, Spain, June 28 - July 2, 2010, Proceedings》中找到。以下是文章样例的链接:

https://www.google.com/books/edition/Objects_Models_Components_Patterns/hvzmnCtNffUC?hl=en&gbpv=1&dq=moles+halleux&pg=PA253

这里是书籍的链接:

https://www.google.com/books/edition/Objects_Models_Components_Patterns/hvzmnCtNffUC?hl=en&gbpv=1&dq=Objects,+Models,+Components&printsec=frontcover

Pex和Moles在《实用Microsoft Visual Studio 2015》、《真实世界.NET、C#和Silverlight》、《使用Visual Studio进行敏捷软件工程》、《Pro .NET最佳实践》中被提及。请参阅“Pex和Moles-针对.NET的隔离和白盒单元测试”。

http://research.micvrosoft.com/projects/pex/

这 3 个视频在 Archive.org 上的最新 URL 是:

https://web.archive.org/web/20210917122427/http://channel9.msdn.com/Blogs/channel9spain/Microsoft-PEXMOLES--advanced-Unit-Testing-aspects-13

https://web.archive.org/web/20210917131545/http://channel9.msdn.com/Blogs/channel9spain/Microsoft-PEXMOLES--advanced-Unit-Testing-aspects-23

https://web.archive.org/web/20210917141034/http://channel9.msdn.com/Blogs/channel9spain/Microsoft-PEXMOLES--advanced-Unit-Testing-aspects-33

更多与Peli de Halleux相关的视频:

https://web.archive.org/web/20210514205423/https://channel9.msdn.com/Shows/Going+Deep/Nikolai-Tillman-and-Peli-de-Halleux-Inside-Code-Digger

https://web.archive.org/web/20210624042526/https://channel9.msdn.com/Blogs/matthijs/Pex-Unit-Testing-of-SharePoint-Services-that-Rocks


目前您的回答内容不够清晰,请[编辑]以添加更多细节,帮助其他人了解它是如何回答问题的。您可以在帮助中心找到更多编写优秀答案的信息。 - Community
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。如果链接页面更改,仅有链接的答案可能会失效。-【来自审查】 - user16217248

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接