使用Unity 实现ASP.NET Web API 依赖注入
DI/IoC 的设计前面已经讲过好几次了,简单的一段话说明就是:「目标对象与外部相依的方式仅相依于 interface,而相依 interface 的 instance 透过 constructor 或 public property 来让外部可以注入相依实体」。 而 DI framework 也是相当多种,这篇文章就简单介绍怎么在 Web API 项目中,简单快速地 adopt Enterprise Library 中的 Unity 。
先建立一个 ASP.NET MVC project, 选择 Web API ,会看到预设长出来的 Controller ,以 ValuesController 的 Get() 为例,程序代码如下所示:
1.// GET api/values2.public IEnumerable<string> Get()3.{4. return new string[] { "value1", "value2" };5.}假设使用 IoC 的设计方式, ValuesController.Get() 方法是透过 IOrderService 这个接口来取值,那么先新增一个 ValuesController 的 constructor ,参数传入 IOrderService ,如下所示:
01.public class ValuesController : ApiController02.{03. private IOrderService _orderService;04. public ValuesController(IOrderService orderService)05. {06. this._orderService = orderService;07. }08. 09. // GET api/values10. public IEnumerable<string> Get()11. {12. //return new string[] { "value1", "value2" };13. return this._orderService.GetValues();14. }15. 16.}17. 18.public interface IOrderService19.{20. IEnumerable<string> GetValues();21.}新增一个实作 IOrderService 的 concrete class, 称为 JoeyOrderService ,程序代码如下所示:
1.public class JoeyOrderService : IOrderService2.{3. public IEnumerable<string> GetValues()4. {5. return new string[] { "joey1", "joey2" };6. }7.}假设需求是希望 ValuesController depend on IOrderService ,在实际上是注入 JoeyOrderService ,在使用时不需要再 new ValuesController(new JoeyOrderService) 这么麻烦,拿到 ValuesController 时相关的相依对象都已经被初始化好了,我们只需要使用 DI framework,注册 IOrderService 使用 JoeyOrderService 即可。
这边使用 Unity 来实作这一段,请在 NuGet 加载 Unity.WebAPI。
除了相关组件参考以外, NuGet 还加入了一支 Bootstrapper.cs ,打开来会看到程序代码如下:
01.using System.Web.Http;02.using Microsoft.Practices.Unity;03. 04.namespace MvcUnitySample05.{06. public static class Bootstrapper07. {08. public static void Initialise()09. {10. var container = BuildUnityContainer();11. 12. GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);13. }14. 15. private static IUnityContainer BuildUnityContainer()16. {17. var container = new UnityContainer();18. 19. // register all your components with the container here20. // e.g. container.RegisterType<ITestService, TestService>(); 21. 22. return container;23. }24. }25.}从批注可以看到,只需要加入 container.RegisterType<TFrom, TTo>() 即可,这边的例子只需要把 IOrderService 与 JoeyOrderService 注册在一起即可,如下所示:
01.public static class Bootstrapper02.{03. public static void Initialise()04. {05. var container = BuildUnityContainer();06. 07. GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);08. }09. 10. private static IUnityContainer BuildUnityContainer()11. {12. var container = new UnityContainer();13. 14. container.RegisterType<IOrderService, JoeyOrderService>();15. return container;16. }17.}接着打开 Global.asax.cs ,在 Application_Start() 的时候,呼叫 Bootstrapper.Initialise() 即可,如下所示:
01.public class WebApiApplication : System.Web.HttpApplication02.{03. protected void Application_Start()04. {05. Bootstrapper.Initialise();06. AreaRegistration.RegisterAllAreas();07. 08. WebApiConfig.Register(GlobalConfiguration.Configuration);09. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);10. RouteConfig.RegisterRoutes(RouteTable.Routes);11. BundleConfig.RegisterBundles(BundleTable.Bundles);12. }13.}这样就大功告成了。我们只做了几件事:
- 把相依的 interface 拉到 constructor or public property ,供外部注入
- 透过 NuGet 加载 Unity.WebAPI
- 在 Bootstrapper 的 BuildUnityContainer() 中注册 interface 对应的 instance type
- 在 Global.asax 中,呼叫 Bootstrapper 的初始化。
来看一下实际的结果,如下图所示:
为什么还需要透过 DI framework 来决定相依对象呢?原因如下:
- 这件事不属于 context 端负责,因为 context 端应该只负责用,而不负责生成目标对象。
- 当对象分割较为独立时,使用一个对象,其相关相依接口可能不少,而对应该接口的实体,也可能还有相依其它接口。因此可能得一大串的 new 之后,才能正常使用一个相依对象。透过 DI framework 的 auto-wiring,会在生成对象的同时,检查 constructor 所使用到的对象,或是标记需要注入的 public property,来产生对应的相依对象自动注入。这样可以节省相当多生成对象的动作。
上面的例子是透过 constructor, 如果希望透过 property 来做注入,也相当简单,只需要在 property 上标示:[Microsoft.Practices.Unity.Dependency]这个 Attribute 即可,程序代码如下所示:
01.public class ValuesController : ApiController02.{03. //private IOrderService OrderService;04. //public ValuesController(IOrderService orderService)05. //{06. // this._orderService = orderService;07. //}08. 09. [Microsoft.Practices.Unity.Dependency]10. public IOrderService OrderService { get; set; }11. 12. // GET api/values13. public IEnumerable<string> Get()14. {15. //return new string[] { "value1", "value2" };16. return this.OrderService.GetValues();17. }18.}这样子效果是一样的。 现在 NuGet 已经相当方便了,如果已经有使用 IoC 的设计,就强烈建议使用方便的 DI framework 来解决生成对象跟相依对象的问题。
原文地址:http://www.it165.net/pro/html/201310/7485.html
使用Unity 实现ASP.NET Web API 依赖注入的更多相关文章
- Web API 依赖注入与扩展
与 MVC 类似, Web API 提供了System.Web.Http.Services.IDependencyResolver 接口来实现依赖注入, 我们可以很容易的用 Unity 来实现这个接口 ...
- ASP.NET Web API中的依赖注入
什么是依赖注入 依赖,就是一个对象需要的另一个对象,比如说,这是我们通常定义的一个用来处理数据访问的存储,让我们用一个例子来解释,首先,定义一个领域模型如下: namespace Pattern.DI ...
- Dependency Injection in ASP.NET Web API 2 (在web api2 中使用依赖注入)
原文:http://www.asp.net/web-api/overview/advanced/dependency-injection 1 什么是依赖注入(Dependency Injection) ...
- ASP.NET Web API - 使用 Castle Windsor 依赖注入
示例代码 项目启动时,创建依赖注入容器 定义一静态容器 IWindsorContainer private static IWindsorContainer _container; 在 Applica ...
- ASP.NET Web API实践系列02,在MVC4下的一个实例, 包含EF Code First,依赖注入, Bootstrap等
本篇体验在MVC4下,实现一个对Book信息的管理,包括增删查等,用到了EF Code First, 使用Unity进行依赖注入,前端使用Bootstrap美化.先上最终效果: →创建一个MVC4项目 ...
- ASP.NET Web API 中的返回数据格式以及依赖注入
本篇涉及ASP.NET Web API中的返回数据合适和依赖注入. 获取数据 public IEnumerable<Food> Get() { var results = reop.Get ...
- 使用Autofac在ASP.NET Web API上实现依赖注入
在ASP.NET Web API里使用Autofac 1.通过NuGet安装Autofac.WebApi(当时安装的是Autofac 3.1.0) PM > Install-Package Au ...
- asp.net web api的自托管模式HttpSelfHostServer可以以控制台程序或windows服务程序为宿主,不单单依赖于IIS web服务器
Self-Hosting ASP.NET Web API http://theshravan.net/self-hosting-asp-net-web-api/ http://www.piotrwal ...
- ASP.NET Web API实践系列07,获取数据, 使用Ninject实现依赖倒置,使用Knockout实现页面元素和视图模型的双向绑定
本篇接着上一篇"ASP.NET Web API实践系列06, 在ASP.NET MVC 4 基础上增加使用ASP.NET WEB API",尝试获取数据. 在Models文件夹下创 ...
随机推荐
- postgresql 免安装版使用
免安装版 postgresql 使用 1.首先使用 initdb 初始化数据目录 initdb --pgdata=data --encoding=UTF8 --locale=C 2.启动 postgr ...
- linux中安装JDK linux中安装Tomcat linux中安装Mysql 及故障解析 linux系统安装redis
Linux 安装JDK 配置完环境变量后无法使用 java -version 无法打开 通过下面语句 将32位文件与当前系统64位兼容 (有待补充32位查法)sudo yum install glib ...
- Junit 测试 @Test 红名问题
准备测试,如上图,都是红名 Ctrl+1 或者鼠标放在@Test上 鼠标放在@Test上出现上面这种就可直接点击安装了 如果是下边这种 Test is not an annotation type,一 ...
- MySQL存储引擎MyISAM与InnoDB
一. MySQL存储引擎MyISAM与InnoDB如何选择 MySQL有多种存储引擎,每种存储引擎有各自的优缺点,可以择优选择使用:MyISAM.InnoDB.MERGE.MEMORY(HEAP).B ...
- vim指令,快捷键汇总
Vim 命令.操作.快捷键全集 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令. 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vi ...
- $.each() 循环遍历完后阻止再执行的办法
jquery each循环遍历完再执行的方法 因为each是异步的 所以要加计数器. query each循环遍历完再执行的方法 因为each是异步的 所以要加计数器.var eachcount=0; ...
- MySQL视图、事务
view(视图):虚拟表主要用来看(查)数据基表的数据变化会在视图中体现出来 权限控制将多表查询的结果整合在视图中方便用户查看 create view v1 as select ...查询语句WITH ...
- oracle下表空间、用户创建以及用户授权流程
Oracle,表空间的建立.用户创建以及用户授权 主要是以下几步,挑选需要的指令即可: # 首先以scott用户作为sysdba登陆 conn scott/tiger as sysdba #创建用户 ...
- ubuntu修改IP地址和网关的方法
一.使用命令设置Ubuntu IP地址 1.修改配置文件blacklist.conf禁用IPV6 sudo vi /etc/modprobe.d/blacklist.conf 表示用vi编辑器(也可以 ...
- filebeat的安装及配置
概述:Filebeat是一个日志文件托运工具,在你的服务器上安装客户端后,filebeat会监控日志目录或者指定的日志文件,追踪读取这些文件(追踪文件的变化,不停的读),并且转发这些信息到elasti ...