InfoQ

InfoQ

新闻

我的书签

登录注册 以永久保存书签。

该内容已经被标记书签!

标记书签错误,请重试!

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

作者 Hartmut Wilms 译者 陈黎夫 发布于 2008年1月11日

领域
语言 & 开发,
企业架构
主题
Web服务 ,
.NET ,
.NET框架
标签
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

深度内容

专访Jeffery Richter:Windows 8是微软的重中之重

Jeffery Richter以其多本Windows核心技术的经典著作而闻名,同时,他深入掌握微软的.NET等一系列核心技术,2012年1月,Jeffery Richter在北京接受了InfoQ中文站的专访,谈到Windows 8和WinRT编程,并就异步编程、Windows编程中的可扩展性、性能和安全性方面给出自己的建议。

应用云平台的可用性——从新浪SAE看云平台设计

云计算平台的可用性,相比传统互联网服务而言,更加复杂和困难,也更具有挑战性。本文借助新浪SAE云平台为读者讲述了云平台可用性的定义、如何打造高可用的平台,以及对云计算的用户提出了建议。

JVM定制改进 @ 淘宝

淘宝高度重视Java平台的健康发展,组建了一个团队专注于Java平台的底层部分的性能、功能与稳定性改进;工作主要基于OpenJDK中的HotSpot VM开展,其中一些通用的功能随后也会逐渐反馈给OpenJDK社区。希望能与使用Java平台开发应用的大家交流经验。
本次演讲视频录制于QCon杭州2011

"伤得起"的云计算应用——对云端应用之架构的思考

2011年4月21日至22日是值得云计算从业者纪念的日子。Amazon的IaaS服务出现故障,导致许多商业网站的服务中断,影响非常严重。作为云计算用户,我们需要思考的是,如何保证即便在云服务不可用的情况,我们的应用架构仍然能够屹立不倒?本文正是站在云计算用户的角度试图探讨这一问题。

让交付的速度跟上思考的速度

12人的技术团队,4组刀片服务器,每月20亿的访问量,每日1次准时部署,99.9%的可用性。这可能吗?当然。想知道如何做的吗?百姓网将与您分享他们在DevOps实践过程中的经验和技巧。
本次演讲视频录制于QCon杭州2011

架构之路——穿行在产品和业务之间

篱笆作为一家起源于社区的电子商务公司,反映到技术层面就是同时要面对产品和业务,以及经营战略的变化调整。如何在产品和业务的夹缝之间完成技术架构的抽象与平衡,寻找更有效的价值定位,这当中有些经验教训和个人感悟愿与众人分享。
本次演讲视频录制于QCon杭州2011

特性注入:成功三部曲

本文将对特性注入以及相关方法做一个扫盲性的介绍。我们会解释这个框架的关键要素,并附上实例来证实它们。为了让文章保持相对较短,我们不会深入到某个工具或方法中,而是会给出一些参考资料,以便大家做进一步的研究。

解析JDK 7的动态类型语言支持

随着JDK 7的发布,字节码指令集终于迎来了第一位新成员——invokedynamic指令。这条新增加的指令是JDK 7实现“动态类型语言(Dynamically Typed Language)”支持而进行的改进之一,也是为JDK 8可以顺利实现Lambda表达式做技术准备。在这篇文章中,我们将去了解JDK 7这项新特性的出现前因后果和它的意义。