InfoQ

新闻

在WCF服务的实现中进行依赖注入

作者 Hartmut Wilms 译者 陈黎夫 发布于 2008年1月11日 上午5时24分

社区
.NET
主题
.NET框架,
Web服务
标签
依赖注入,
WCF

实现WCF服务的一个常见的做法就是将程序分为服务、业务逻辑以及数据访问层。而这些层次之间的关系则恰好可以通过依赖注入容器在程序运行时进行关联。

Don Smith服务架构概念模型(Service Architecture Concept Model)一文中提出了WCF服务门面的设计方法。依照这样的设计,服务将发布一个由业务逻辑层组件构成的接口/契约。而这些业务逻辑层组件则又依赖于资源访问层中的数据访问组件。

一般来讲,层与层之间的依赖关系均被硬编码在服务以及组件的实现代码中,这也让单元测试显得举步维艰。为了改善这种情况,Pablo M. Cibraro通过实现一个WCF依赖注入行为,在运行时将组件之间的关系进行注入。在他的方法中,作为依赖注入容器的是ObjectBuilder,而在Oran DennisonWCF服务的依赖注入中,却异曲同工地选择了Spring.NET

如下代码演示了Oran的实现方式中建立依赖关系的方法:

[ServiceContract]
public interface IServiceContract {
[OperationContract]
...
}

public class ServiceLayer : IServiceContract {
IBusinessLogic _businessLogic;

public ServiceLayer(IBusinessLogic businessLogic) {
_businessLogic = businessLogic;
}
...
}

public interface IBusinessLogic {
...
}

public class BusinessLogic : IBusinessLogic {
IDataAccess _dataAccess;

public BusinessLogic(IDataAccess dataAccess) {
_dataAccess = dataAccess;
}
...
}

public interface IDataAccess {
...
}

public class DataAccess : IDataAccess {
...
}

可以看到,服务层的实现则依赖于业务逻辑组件,而业务逻辑的实现则相应地依赖于数据访问组件。这样,建立依赖关系的代码将如下所示:

return new ServiceLayer(new BusinessLogic(new DataAccess()));

一般来讲,依赖注入容器是通过在配置中提供实现类到接口的映射关系来实现注入的。而这些配置则能够很容易地在运行时根据需要进行调整或改变。例如,有时为了方便单元测试,我们可能需要改用Mock对象。对于这种情况,Pablo给出了解决方案:

这简直是小菜一碟——(对于依赖注入容器)我们所要做的只是调整一下映射规则,否则容器无法知晓应该创建哪种对象的实例。现在就让我们通过一种可扩展的方法尝试配置该WCF服务。我们都知道,WCF支持一个名为IInstanceProvider的扩展,用来控制WCF实例的生命周期。我们正是要通过它来加载新的代码,并在运行时将层与层之间的依赖关系注入。
public class DIInstanceProvider : IInstanceProvider {   
[...]


public object GetInstance(InstanceContext instanceContext, Message message) {
DependencyContainer container = new DependencyContainer();
foreach (TypeMapping typeMapping in this.typeMappings) {
container.RegisterTypeMapping(typeMapping.TypeRequested, typeMapping.TypeToBuild);
}
return
container.Get(this.serviceType);
}
[...]
}

随后,该DIInstanceProvider将通过一个IServiceBehavior在运行时接入到分配程序中。类型的映射是通过一个新的WCF配置节实现的,该配置节可以通过BehaviorExtensionElement从配置文件中读取,并传递给DIServiceBehavior实例。在Pablo给出的示例中,配置文件如下所示:

<behaviors>

      <serviceBehaviors>

        <behavior name="Behaviors1">

          <dependencyInjection>

            <typeMappings>

              <add name="DataAccess" typeRequested="SampleService.ICustomerDataAccess, SampleService"

                    typeToBuild="SampleService.CustomerDataAccess, SampleService"/>

              <add name="BusinessComponent" typeRequested="SampleService.ICustomerBusinessComponent, SampleService"

                    typeToBuild="SampleService.CustomerBusinessComponent, SampleService"/>

            typeMappings>

          dependencyInjection>

        behavior>

      serviceBehaviors>   

behaviors>

Pablo给出了他的示例代码。我们也能够容易地将该代码转化为Oran等使用其他依赖注入容器(例如Castle Windsor)的实现方法。

查看英文原文:Injecting Implementation Dependencies into WCF Services

深度内容

和Google互补的搜索引擎Wolfram|Alpha

Wolfram|Alpha与Google究竟是什么关系,Wolfram|Alpha自己是如何定位的?Wolfram|Alaph在多大程度上是语义网搜索呢?InfoQ中文站就等等这些问题采访了Wolfram研究公司中国区商务经理王翔。

SOA契约成熟度模型

本文说明了所推荐的契约版本管理设计策略是如何与SOA成熟度模型发生联系的。文章目的是为实现版本管理和可组合性提供一个路线图。

数据服务简介

Vijay Narayanan在这篇文章中对数据服务的几个方面进行了介绍,它们都是SOA实践者和数据架构师感兴趣的内容。本文对数据服务的几个方面进行了介绍,包括需求定义,基本原理和好处、范围、开发以及消费模式。

分块云计算

在本文中,Jimmy Nilsson描述了一种他在过去数年间观察到的一种正在缓慢成长的架构风格,他把这种风格称为“分块云计算”。

豆瓣网技术架构变迁

罗马不是一天建成的,豆瓣的技术架构也是随着用户规模的增长一直在持续变化中。在本次演讲中,豆瓣的首席架构师洪强宁将与大家一起分享从上线时的单台服务器架构开始一直到现在的豆瓣架构变迁历程。

融合思想:深入探索S#arp架构

Billy McCafferty展示了S#arp架构,它在ASP.NET MVC框架的基础上,荟萃了当今的最佳实践,应用在ASP.NET Web应用程序的架构设计中。

王雷谈开源以及新兴市场计划

中国作为新兴市场中的新兴市场,是Sun在美国之外实施SSE(SUN Startup Essentials)项目重点关注的地区。在QCon Beijing 2009期间,InfoQ中文站有幸对此项目的负责人王雷先生进行了采访,探讨了关于开源、新兴市场、SSE等话题。

使用HTML5构建下一代的Web Form

HTML5 是由 WHATWG发起的,最开始的名称叫做Web Application 1.0,而后这个标准吸纳了Web Forms 2.0的标准,并一同被W3C组织所采用,合并成为下一代的HTML5标准。