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 上的实际运用 ...
随机推荐
- spring boot jar 部署linux服务器
用命令启动spring boot 项目,一旦终端命令窗口关闭,项目也就关闭了,所以我们采用脚本的方式来运行jar 正常命令 java -jar xxx.jar 脚本启动,vim 创建 start.sh ...
- SQL server添加链接服务器脚本
---恢复内容开始--- exec sp_addlinkedserver 'ZZSJK','','SQLOLEDB','192.168.10.22' --链接服务器名称 ‘’ ip地址exec s ...
- spring-boot-starter-parent 1.3.6.RELEASE
2016-11-17 23:43:17.979 DEBUG 3944 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Creating share ...
- 度小于所述过程:KanboxEnt.exe
在防火墙管理.见未知的过程"KanboxEnt.exe" 程序信息: 版权声明:本文博主原创文章.博客,未经同意不得转载.
- numpy 代码优化(一)—— 常见手段
选择使用 numpy 库的应有之义就在于:应当以矢量化的方式(vectorized operations)来避免迭代操作(iterations),numpy 下的迭代操作执行起来十分耗时. impor ...
- 开发Android项目中使用androidannotations
前言 最近接手了一个工程,使用了androidannotations,因为以前使用过butterknife所以有似曾相识的感觉,但是有些用法还是不一样,所以就花时间学习了下androidannotat ...
- cocos2d-x 打开控制面板
于cocos2dx反过来,我们所熟悉的控制台输出,可以查看日志,例如C介面printf();性能. int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTA ...
- 不积跬步无以至千里(C语言笔记)
第一章 初始C程序 1.C程序结构 简单来说,一个C程序就是由头文件和函数组成 头文件 一条编译预处理命令:作用是在对C程序进行正式编译 ...
- PowerDesigner模型分类
原文:PowerDesigner模型分类 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/zjws23786/article/details/8005 ...
- SQL Server 2017 正式发布:同时支持 Windows 和 Linux(现在看下来,当年那德拉的“云优先,移动优先”是有远见的,而且是有一系列的措施和产品相配合的,只是需要一点时间而已。真是佩服!!)
微软在去年 3 月首次对外宣布了 Linux 版的 SQL Server,并于今年 7 月发布了首个公开 RC 版.前几日在美国奥兰多召开的微软 Ignite 2017 大会上,微软宣布 SQL Se ...