Welcome

首页 / 软件开发 / .NET编程技术 / emit的基本操作

emit的基本操作2014-06-26最近收到《.NET 安全揭秘》的读者的邮件,提到了书中很多大家想看到的内 容却被弱化了,我本想回复很多内容因为书的主旨或者章节规划的原因只是概说 性的,但是转念一想,读者需要的,不正是作者该写的吗?因此我准备把邮件中 的问题一一搬到博客中,以博文的形式分享给大家。

今天要谈论的主题是Emit,反射的孪生兄弟。想要通过几篇博客详尽的讲解 Emit也是很困难的事情,本系列计划通过完成一个简单的Mock接口的功能来讲解 ,计划写三篇博客:

2)        说说Emit (中)ILGenerator;

<p CxSpLast" style=";margin-left: 45pt">3)        说说Emit (下)Emit在AOP和单元测试中的应用;

这几篇博客不可能涵盖Emit所有内容,只希望能让您知道Emit是什么,有哪些 基本功能,如何去使用。

1.1 动态实现接口的技术需求

第一个需要动态实现接口的需求,是我在开发中遇到的,具体的业务场景会在 《说说Emit (下) Emit在AOP和单元测试中的应用》中细说,先简要描述代码级别 要实现的内容。首先我们有类似图1所示的以Before和After结尾的成对出现的方 法若干。

图1 若干成对方法

我们根据一定的规则对上图所示的方法进行分类(分类的规则暂且不提),在 实际调用过程中,不会直接调用上面的方法,而是调用一个名为 IAssessmentAopAdviceProvider的接口的实例,该接口定义如下:

publicinterfaceIAssessmentAopAdviceProvider

 {

     object Before(object value);

     object After(object beforeResult, object value);

   }

负责创建该接口的工厂类定义如下:

staticclassAdviceProviderFactory

 {

    internalstaticIAssessmentAopAdviceProvider GetProvider(AdviceType adviceType, string instanceName,string funcName,MvcAdviceType mvcAdviceType)

     {

        //创建接口的实例

     }

 }

该工厂的职责是根据传入的参数,选择类似图1中的合适的成对方法动态创建 一个IAssessmentAopAdviceProvider接口的实例,然后返回供调用方使用。当然 如果不使用Emit也能实现这样的需求,这里我们只讨论使用Emit如何实现。

第一个需求简单介绍到这里,我们看第二个需求。现在我要在单元测试中测试 某个依赖IAssessmentAopAdviceProvider的类,我们控制 IAssessmentAopAdviceProvider的行为该怎么办呢?如果你做过单元测试,一定 会想到Mock,我们可以使用Moq:

Mock<IAssessmentAopAdviceProvider> assessmentAopAdviceProviderMocked = newMock<IAssessmentAopAdviceProvider>();

assessmentAopAdviceProviderMocked.Setup(t => t. Before (It.IsAny<object>())).Returns(expectObject);

现在我也想实现这样的功能,该怎么做呢?您先不要惊讶,实现完整的Mock功 能要实现一整套动态代理的框架,我还没这个雄心壮志,这里为了演示Emit,我 以最简单的方式实现对IAssessmentAopAdviceProvider接口的Before方法的Mock ,而且只针对某个特例,只保证这个特例能被调用即可。感兴趣的读者可以去读 一读Moq的源码。

OK,技术需求到此结束,下面我们开始动手吧!