ASP.NET 5 牛刀小試(二):加入第三方 DI 容器
上回介绍了 ASP.NET vNext 自带容器的基本用法,这次要试试把 ASP.NET vNext 的自带容器换成 Autofac。
这一次,在编写范例程序的过程中,光是解决 KRE 与相关套件的版本不合的问题,就花了我个把小时。所以还是得先提醒一下,目前 ASP.NET vNext 还不是正式版,所以本文的操作步骤与代码不一定符合你的开发环境。
如果你有兴趣了解我最后一个碰到的问题,以及最后是怎么解决的。可以看这帖:https://github.com/aspnet/Home/issues/218(至于更早之前碰到的问题就略过不提了。不重要,因为是发生在比较早的 beta-1 版本。
本文范例所使用的开发环境:
- Windows Server 2012 R2
- Visual Studio 2015 Preview
- KRE-CLR-x86.1.0.0-rc1-10798
小引
上回提到,ASP.NET vNext 的自带容器支持四种生命周期模式:Instance、Singleton、Transient、Scoped。而且,上一次的范例程序也演示了自带容器的基本用法。这一次要试试把 ASP.NET vNext 的自带容器换成 Autofac。
在此之前,先补充一点基本观念。
在 ASP.NET vNext 之前,.NET Framework 对 DI(dependency injection)的支持并不那么彻底,比较像是附加功能。到了 ASP.NET vNext ,DI(dependency injection)摇身一变,已成为一级公民。明确地说,现在不仅自带了一个小巧的 DI 容器,同时也提供了适度的弹性,能够与其他第三方容器衔接。不过,自带的 DI 容器比较阳春,无法满足某些需求,例如欲解析之类型有多个构造函数时,自带的 DI 容器无法让我们指定使用特定构造函数。像这类更细致的控制,还是得靠其他第三方 DI 框架才行。
ASP.NET vNext 的自带 DI 容器
ASP.NET vNext 之所以能够搭配其他 DI 框架一起使用,是因为它在 DI 容器实现之上提供了一个抽象层。具体来说,这个抽象层就是 System.IServiceProvider 接口,它定义了自带 DI 容器应该具备哪些功能。.NET Framework 的其他组件(如 MVC、路由、SignalR、Entity Framework 等)都支持这个接口,而且也只会使用这个接口所定义的 DI 相关功能。所以基本上,ASP.NET vNext 的自带 DI 容器就等于是个全局的 Service Locator。
不过,这并不代表你的应用程序也受限于此接口——你可以写一个自定义的类型来封装你惯用的 DI 容器,然后把自带的 IServiceProvider 组件换掉。如此一来,所有服务解析的工作就会交给你指定的自定义容器来处理。此外,你也可以让自定义容器只解析特定类型的服务,而把其他不需要特别处理的服务类型丢回(fallback)给自带的容器来解析。
在 ASP.NET vNext 中,由于所有的内部框架/组件都是通过同一个容器来注册服务,相依对象便更容易跨越框架边界(四处流窜?),注入至以往不容易到达的地方。
自带的 DI 容器支援下列几种生命周期:
- Instance:解析特定服务类型时,总是返回由你自行建立的特定对象。
- Transient:每次解析时都建立新的对象。
- Singleton:每次解析时都返回先前已建立的同一个对象。该对象等于是全局(对整个容器而言)共享的单一对象。
- Scoped:针对特定范围共享同一个对象。作用等同于特定范围内的 Singleton。
接着要来试试把 Autofac 加入至 ASP.NET vNext 的 DI 框架。
BYOC to ASP.NET vNext
前面提过,ASP.NET vNext 允许你使用自定义容器来取代自带的 DI 容器,但不必是完全取代,而是可以让 ASP.NET 优先用你提供的容器,而让自带的容器退居二线,担任「备援」的角色。正因为如此,我们通常不说「抽换自带容器」,而说「把你的容器加入 ASP.NET vNext」,亦即 BYOC (Bring Your Own Container) to ASP.NET vNext。
延续上回的范例程序,原本的 Startup 类型是这么写:
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseMvc();
} public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(); services.AddScoped<ITimeService, TimeService>();
}
}
其中 ConfigureServices 方法使用了自带容器来注册 TimeService 服务。这个部分要改用 Autofac 来做。
注:ASP.NET vNext 框架会先调用 Startup 类型的 ConfigureServices 方法,然后再调用 Configure 方法。
第一步,为项目加入必要的组件引用。这个部分可直接修改 project.json,如下所示:
{
"webroot": "wwwroot",
"version": "1.0.0-*",
"exclude": [
"wwwroot"
],
"packExclude": [
"**.kproj",
"**.user",
"**.vspscc"
],
"dependencies": {
"Microsoft.AspNet.Server.IIS": "1.0.0.0-rc1-10790",
"Microsoft.AspNet.Mvc": "6.0.0.0-rc1-12170",
"Microsoft.Framework.DependencyInjection": "1.0.0.0-rc1-10655",
"Microsoft.Framework.DependencyInjection.Autofac": "1.0.0.0-rc1-10655"
},
"frameworks": {
"aspnet50": {
"dependencies": {}
}
}
}
提醒:dependencies 区块中的各组件的版本号码可能会决定这个简单的范例程序要花你三分钟还是三小时才能完成。(等到 ASP.NET vNext 发布正式版本之后应该就不会有这些状况了)
接着修改 Startup 类型的 ConfigureServices 方法,改成这样:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc(); var builder = new ContainerBuilder();
builder.Populate(services); builder.RegisterType<TimeService>().As<ITimeService>(); IContainer container = builder.Build();
return container.Resolve<IServiceProvider>();
}
上面这段代码有几个地方值得注意:
- Populate 是个扩展方法,由 Microsoft.Framework.DependencyInjection.Autofac 组件提供。此扩展方法会把传入的服务描述清单中的服务全部注册至 Autofac 容器。
- 注意 ConfigureServices 方法的返回类型从原先的 void 改成了 IServiceProvider。这里返回的对象实际类型会是 AutofacServiceProvider。如此一来,ASP.NET vNext 框架接收到你返回的 AutofacServiceProvider 对象之后,就会把它设定成默认的 DI 容器。
试执行应用程序,结果应该和前一个版本相同。
(注:本文内容将会连同上一集,加以补充完善之后,更新至电子书《.NET 依赖注入》里面。)
参考資料
- Dependency Injection in ASP.NET vNext by Robin Sedlaczek
- System.Exception: TODO: No service for type 'Microsoft.Framework.DependencyInjection.ServiceLookup.IServiceManifest' has been registered.
ASP.NET 5 牛刀小試(二):加入第三方 DI 容器的更多相关文章
- ASP.NET 5 (vNext) 牛刀小試:自帶 DI 容器
小引 在 ASP.NET 5(vNext)之前,亦即 MVC 4/5.Web API 2 的时代,MVC 与 Web API 框架彼此有非常相似的设计,却是以不同的代码来实现.现在,ASP.NET 5 ...
- 微信小程序二维码推广统计
微信小程序可以通过生成带参数的二维码,那么这个参数是可以通过APP的页面进行监控的 这样就可以统计每个二维码的推广效果. 今天由好推二维码推出的小程序统计工具HotApp小程序统计也推出了带参数二维码 ...
- ASP.NET Web API 控制器创建过程(二)
ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...
- asp.net 生成、解析条形码和二维码
原文 asp.net 生成.解析条形码和二维码 一.条形码 一维码,俗称条形码,广泛的用于电子工业等行业.比如我们常见的书籍背面就会有条形码,通过扫描枪等设备扫描就可以获得书籍的ISBN(Intern ...
- SQL开发中容易忽视的一些小地方(二)
原文:SQL开发中容易忽视的一些小地方(二) 目的:继上一篇:SQL开发中容易忽视的一些小地方(一) 总结SQL中的null用法后,本文我将说说表联接查询. 为了说明问题,我创建了两个表,分别是学生信 ...
- ASP.NET MVC 單元測試系列
ASP.NET MVC 單元測試系列 (7):Visual Studio Unit Test 透過 Visual Studio 裡的整合開發環境 (IDE) 結合單元測試開發是再便利不過的了,在 Vi ...
- 微信小程序参数二维码6问6答
微信小程序参数二维码[基础知识篇],从6个常见问题了解小程序参数二维码的入门知识. 1.什么是小程序参数码? 微信小程序参数二维码:针对小程序特定页面,设定相应参数值,用户扫描后进入相应的页面. 2. ...
- ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)
前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ...
- ASP.NET Core 基于JWT的认证(二)
ASP.NET Core 基于JWT的认证(二) 上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用 ...
随机推荐
- 【codeforces 785C】Anton and Fairy Tale
[题目链接]:http://codeforces.com/contest/785/problem/C [题意] 容量为n的谷仓,每一天都会有m个谷子入仓(满了就视为m);第i天 会有i只鸟叼走i个谷子 ...
- shell自动化下载、安装、配置nginx
#!/bin/bash auto config nginx server #by author www.jfedu.net #2018年5月14日17:25:52 N_PAR="vim lr ...
- HashMap工作原理的介绍!
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道HashTable和HashMap之间的区别,那么为何这道面试题如此 ...
- 微信公众平台消息接口开发(26)从Hello2BizUser文本到subscribe事件
微信公众平台 微信公众平台开发模式 消息接口 企业微信公众平台 Hello2BizUser subscribe 订阅事件 作者:方倍工作室 原文:http://www.cnblogs.com/txw1 ...
- arcserver开发小结(三)
一.关于网络数据集的制作 由于要做实现网络分析的功能,而手中却没有网络数据集,关于网络数据集的制作,网上也有不少的资料.我参考的是ESRI为我们提供的帮助文档(Network_Analyst_Tuto ...
- VC6下深入理解new[]和delete[](在多线程下new和delete的时候,必须选择上多线程库,不然可能造成进程崩溃)
多少年了,一直处于C与C++混用的状态,申请空间一直用malloc,释放空间一直用free,为什么?因为他们好理解易操作,就如同输出一直用printf而不用<<,输入一直用scanf而不用 ...
- WPF3D绘图的基础
原文:WPF3D绘图的基础 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37591671/article/details/69487096 ...
- Angular语法(一)——展示数据
双花括号{{}} 展示数据 title = 'Tour of Heroes'; myHero = 'Windstorm'; <h1>{{title}}</h1> <h2& ...
- windows IIS发布.net core网站的环境配置
1.安装对应的.net core的runtime2.安装Windows Server Hosting下载地址:https://www.microsoft.com/net/download/core#/ ...
- WPF编游戏系列 之六 动画效果(1)
原文:WPF编游戏系列 之六 动画效果(1) 本篇主要针对界面进行动画效果处理.首先在打开或关闭界面时,使其产生动态效果而不是生硬的显示或消失(如下图).其次在鼠标放到关闭窗口图标上时, ...