上回介绍了 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 依赖注入》里面。)

参考資料

ASP.NET 5 牛刀小試(二):加入第三方 DI 容器的更多相关文章

  1. ASP.NET 5 (vNext) 牛刀小試:自帶 DI 容器

    小引 在 ASP.NET 5(vNext)之前,亦即 MVC 4/5.Web API 2 的时代,MVC 与 Web API 框架彼此有非常相似的设计,却是以不同的代码来实现.现在,ASP.NET 5 ...

  2. 微信小程序二维码推广统计

    微信小程序可以通过生成带参数的二维码,那么这个参数是可以通过APP的页面进行监控的 这样就可以统计每个二维码的推广效果. 今天由好推二维码推出的小程序统计工具HotApp小程序统计也推出了带参数二维码 ...

  3. ASP.NET Web API 控制器创建过程(二)

    ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...

  4. asp.net 生成、解析条形码和二维码

    原文 asp.net 生成.解析条形码和二维码 一.条形码 一维码,俗称条形码,广泛的用于电子工业等行业.比如我们常见的书籍背面就会有条形码,通过扫描枪等设备扫描就可以获得书籍的ISBN(Intern ...

  5. SQL开发中容易忽视的一些小地方(二)

    原文:SQL开发中容易忽视的一些小地方(二) 目的:继上一篇:SQL开发中容易忽视的一些小地方(一) 总结SQL中的null用法后,本文我将说说表联接查询. 为了说明问题,我创建了两个表,分别是学生信 ...

  6. ASP.NET MVC 單元測試系列

    ASP.NET MVC 單元測試系列 (7):Visual Studio Unit Test 透過 Visual Studio 裡的整合開發環境 (IDE) 結合單元測試開發是再便利不過的了,在 Vi ...

  7. 微信小程序参数二维码6问6答

    微信小程序参数二维码[基础知识篇],从6个常见问题了解小程序参数二维码的入门知识. 1.什么是小程序参数码? 微信小程序参数二维码:针对小程序特定页面,设定相应参数值,用户扫描后进入相应的页面. 2. ...

  8. ASP.NET Core中使用IOC三部曲(二.采用Autofac来替换IOC容器,并实现属性注入)

    前言 本文主要是详解一下在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期. 这里就不详细的赘述IOC是什么 以及DI是什么了.. emm..不懂的可以自行百度. 目录 ...

  9. ASP.NET Core 基于JWT的认证(二)

    ASP.NET Core 基于JWT的认证(二) 上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用 ...

随机推荐

  1. [Android]使用化名(alias)功能防止相同资源的重复

    在为一个应用匹配不同资源文件的时候,有时可能需要在不同适配类型的资源路径下使用相同的资源文件,这时使用alias方法可以防止相同资源文件的重复,提高效率.以下摘自Android开发文档http://d ...

  2. Ibatis之RowHandler

    如果一个场景:账户表中有1千万账户,现在,我们需要这个1千万账户利息结算业务.需求是基于Ibatis框架来实现这个功能. 如果按照一般的编程模式,我们将编写一个sql,然后调用QueryForList ...

  3. css3中的制作动画小总结

    系列教程 CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation: Transform 在CSS3中transform主要包括以下几种:旋转rotate. ...

  4. redis 学习笔记——持久化

    redis持久化 snapshot数据快照(rdb) 这是一种定时将redis内存中的数据写入磁盘文件的一种方案,这样保留这一时刻redis中的数据镜像,用于意外回滚.redis的snapshot的格 ...

  5. 强烈推荐node包colors

    库链接:colors 在你的 node.js 控制台中获取颜色

  6. 详尽分析世纪之战:360VS腾讯是两个阶层的抗争

    很不错的一篇文字  分析的也很透彻 [转自中国移动http://labs.chinamobile.com/] 来源:搜狐IT 作者:吃熊掌的鱼 2010-11-01 10:11:51 [ 13967阅 ...

  7. iis启动 服务无法在此时接受控制信息。 (异常来自 HRESULT:0x80070425)

    原文:iis启动 服务无法在此时接受控制信息. (异常来自 HRESULT:0x80070425) 问题描述:每隔一段时间应用程序池就会自动停止,报错:服务无法在此时接受控制信息. (异常来自 HRE ...

  8. c语言学习笔记(11)——枚举

    # include <stdio.h> enum WeekDay  //定义了一个数据类型(值只能写一下值) { MonDay, TuesDay, WednesDay, ThursDay, ...

  9. 抛砖引玉 【镜像控件】 WPF实现毛玻璃控件不要太简单

    原文:抛砖引玉 [镜像控件] WPF实现毛玻璃控件不要太简单 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Vblegend_2013/articl ...

  10. ddraw 视频下绘图 不闪烁的方法

    我们假设是在在RGB视频上绘图(直线,矩形等),一般採用双缓冲区继续,使用内存MemoryDC,来实现画的图形在视频上显示不闪烁的功能,可是我们知道用RGB显示视频都是使用GDI进行渲染,这样非常耗C ...