Dependency Injection in ASP.NET Web API 2 (在web api2 中使用依赖注入)
原文:http://www.asp.net/web-api/overview/advanced/dependency-injection
1 什么是依赖注入(Dependency Injection)
依赖,简单来说就是一个对象需要的任何其他对象。具体解释请Google或百度。在我们使用Web api2 开发应用程序时,通常都会遇到Controller 访问库 Repository 问题。
例如:我们定义一个Domain 对象
public class Product |
接下来用Entity Framework 来实现一个简单的仓储ProductRepository
public class ProductsContext : DbContext |
然后,我们创建一个简单ProductController API 控制器,实现两个get 请求
public class ProductsController : ApiController ProductRepository _repository = new ProductRepository(); public IEnumerable<Product> Get() |
看这个类的红色行代码,ProductsContoller 依赖了 ProductRepository ,ProductsContoller 在代码中创建了 ProductRepository 的实例,
用这种方式硬编码,是一个糟糕的注意(bad idea),因为:
1 ) 如果你想用不同实现来 替换ProductRepository ,必须修改 ProductsContoller 类 。(违反了开闭原则)
2 ) 如果ProductRepository 还有其他依赖,你需要在 ProductsContoller 类中实现其他的依赖项,一个大的项目通常都有很多controller ,这会造成大量的实现依赖分散在你的整个项目中。
3) 这很难进行单元测试,因为ProductRepository 已经硬编码在 ProductsContoller 中。对于单元测试,我们应该使用ProductRepository 的mock 或Sub (桩)实例,但这种写法无法进行单元测试。
我们要解决这个问题,只需把ProductRepository 注入到ProductsContoller 类中。 首先重构ProductRepository 实现一个 IProductRespository 接口
public interface IProductRepository |
然后修改controller ,提供一个构造函数传递 IProductRepository 参数
public class ProductsController : ApiController |
这个例子使用了构造函数进行注入,你也可以使用属性或者方法进行注入。(个人建议在一个项目中,统一使用一种注入方式,例如都使用构造函数进行注入)。
现在有一个问题,因为我的程序并不能直接创建一个带参数的Controller。 Web API 程序收到一个路由请求时,创建一个controller ,但是它不知道如何创建一个带IProductRepository 参数的 controller。
到这儿,就该依赖注入登场了!
2 The Web API Dependency Resolver (Web API 依赖注入)
Web API 定义了一个IDependencyResolver 接口来 解析依赖,定义如下:
public interface IDependencyResolver : IDependencyScope, IDisposable |
IDependencyScope 接口有两个方法
1) GetService 创建一个类型实例
2) GetServices 创建一个指定类型对象的集合。
IDependencyResolver 继承 IDependencyScope ,并且添加了一个BeginScope 方法,BeginScope 用来管理对象的生命周期。
当Web API 创建一个controller 实例时,它首先调用IDependencyResolver.GetService 方法,再传入controller 的参数类型。 我们可以使用这个可扩展的钩子 来创建Controller 的实例,解决依赖关系。
如果GetService 返回null,WebAPI 会在controller类 中寻找无参的构造函数。
Dependency Resolution with the Unity Container (使用Unity容器来解决依赖)
虽然我们可以从头写完一个IDependencyResolver 的实现,但这个接口的真正设计目的,是充当Web api 和 现存Container 的桥梁。
Container 是一个软件组件,负责管理依赖。用Container 注册 类型,就可以使用Container 来创建类型的实例。容器会自动识别依赖关系,并且很多容器还可以控制对象的生命周期。
本教程,我们使用微软的 Unity 容器来解决依赖。
在包管理控制台中,输入如下命令,安装unity 。
Install-Package Unity |
接着再实现一个封装了unity 容器的 IDependencyResolver 接口实现类 。
using Microsoft.Practices.Unity; |
注意:
1) 如果GetService 不能解析一个类型,那么必须返回 null
2) 如果GetServices 不能解析一个类型,那么必须返回一个空的集合实例。
不能解析类型时,按上面两种情况处理,不能抛出任何异常。
Configuring the Dependency Resolver 配置依赖解析器
最后一步,在全局 HttpConfiguration 对象的DependencyResolver 属性上设置 依赖解析器
public static void Register(HttpConfiguration config) config.DependencyResolver = new UnityResolver(container); // Other Web API configuration not shown. |
以上代码是写在 Global.asax 文件中的应用程序启动Application_Start() 方法中,
public class WebApiApplication : System.Web.HttpApplication |
5 Dependenecy Scope and Controller Lifetime 依赖范围和控制器的生命周期
每个request都会创建一个controller ,为了管理对象的生命周期,IDependencyResolver 使用一个 Scope 的概念。
dependency resolver 依附 到HttpConfiguration 对象上,有一个全局范围(global scope)。当Web api 创建一个 controller 时, 它调用 BeginScope, 这个方法返回一个IDependencyScope 代表一个子范围。
Web api 在这个子范围中 调用 GetService 方法创建Controller ,当请求完成时,Web api 在这个子范围内调用Dispose 方法,用Dispose 这个方法来释放 Controller 的依赖。
你需要实现BeginScope 取决于你使用的容器,对于Unity ,BeginScope 的实现如下:
public IDependencyScope BeginScope() |
Dependency Injection in ASP.NET Web API 2 (在web api2 中使用依赖注入)的更多相关文章
- 循序渐进学.Net Core Web Api开发系列【11】:依赖注入
系列目录 循序渐进学.Net Core Web Api开发系列目录 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi 一.概述 本篇介绍如 ...
- ASP.NET MVC Web API 学习笔记---Web API概述及程序示例
1. Web API简单说明 近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过 ...
- [Web API] 如何让 Web API 统一回传格式以及例外处理[转]
[Web API] 如何让 Web API 统一回传格式以及例外处理 前言 当我们在开发 Web API 时,一般的情况下每个 API 回传的数据型态或格式都不尽相同,如果你的项目从头到尾都是由你一个 ...
- [Web API] 如何让 Web API 统一回传格式以及例外处理
[Web API] 如何让 Web API 统一回传格式以及例外处理 前言 当我们在开发 Web API 时,一般的情况下每个 API 回传的数据型态或格式都不尽相同,如果你的项目从头到尾都是由你一个 ...
- Web API 2 入门——Web API 2(C#)入门(谷歌翻译)
ASP.NET Web API 2(C#)入门 在这篇文章中 本教程中使用的软件版本 创建一个Web API项目 添加模型 添加控制器 使用Javascript和jQuery调用Web API 运行应 ...
- 如何在 ASP.Net Web Forms 中使用依赖注入
依赖注入技术就是将一个对象注入到一个需要它的对象中,同时它也是控制反转的一种实现,显而易见,这样可以实现对象之间的解耦并且更方便测试和维护,依赖注入的原则早已经指出了,应用程序的高层模块不依赖于低层模 ...
- 开发H5程序或者小程序的时候,后端Web API项目在IISExpress调试中使用IP地址,便于开发调试
在我们开发开发H5程序或者小程序的时候,有时候需要基于内置浏览器或者微信开发者工具进行测试,这个时候可以采用默认的localhost进行访问后端接口,一般来说没什么问题,如果我们需要通过USB基座方式 ...
- ASP.NET Core中的依赖注入(1):控制反转(IoC)
ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了"标准化&qu ...
- ASP.NET Core 中的依赖注入 [共7篇]
一.控制反转(IoC) ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制,ASP.NET通过定义接口的方式对它们进行了 ...
随机推荐
- 1分钟搭建极简mock server
1.无聊的背景.起源: 如今的业务系统越来越复杂庞大,各个功能直接的调用也是多如牛毛,但如果在联调的时候,恰好被调的接口正在开发,怎么办?傻傻的等么,不存在的!这时会搭建一些server来进行mock ...
- 请以excel管理你的接口测试用例
闲话休扯,上需求:自动读取.执行excel里面的接口测试用例,测试完成后,返回错误结果并发送邮件通知. 分析: 1.设计excel表格2.读取excel表格3.拼接url,发送请求4.汇总错误结果.发 ...
- 通过TLS回调函数的反调试
下面是TLS数据结构的定义 typedef struct _IMAGE_TLS_DIRECTORY { DWORD StartAddressOfRawData; DWORD EndAddressOfR ...
- 跨页面传值之Cookie
3.客户端再次访问某站点 浏览器将携带Cookie信息的指令,将获得的信息参与编译. 4.将含有Cookie信息参与编译的页面发回给浏览器 其中如果有相关的设置Cookie的指令.将再次通过浏览器,写 ...
- windows下配置nginx环境
一. nginx软件拷贝 拷贝 nginx文件 到对应的服务目录中 如 E:/service/nginx nginx文件地址: 链接: http://pan.baidu.com/s/1c25oq6O ...
- [转]谷歌Chrome浏览器开发者工具教程—JS调试篇
来源:http://blog.csdn.net/cyyax/article/details/51242720 上一篇我们学习了谷歌Chrome浏览器开发者工具的基础功能,下面介绍的是Chrome开发工 ...
- Quartz使用及注意事项
Quartz使用及注意事项 前提:目前由于公司业务决定,大量使用Quartz,每天固定的时间点执行相应的业务逻辑,,几十个时间点应该是有的,某一个时间点如果没有执行带来的问题是巨大的.Quartz的稳 ...
- Thrift笔记(一)--Hello Demo
Thrift是一个RPC框架 1. 用IDL定义好实体和服务框架,如实体字段名,类型等.服务名,服务参数,返回值等 2. 通过编译器或者说代码生成器生成RPC框架代码 IDL语法,代码生成器的安装使用 ...
- Linux - centos 7 mysql安装
安装 CentOS Linux release 7.1.1503 (Core)下载地址链接:https://pan.baidu.com/s/1c2rWsbm 密码:5nrt #yum -y insta ...
- js获取css的各种样式并且设置他们
js原生获取css样式,并且设置,看似简单,其实并不简单,我们平时用的ele.style.样式,只能获取内嵌的样式,但是我们写的样式基本都在style属性里面; 这里我们就需要: 下面这个代码主要是设 ...