在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
上回介绍了 ASP.NET vNext 自带容器的基本用法,这次要试试把 ASP.NET vNext 的自带容器换成 Autofac。 这一次,在编写范例程序的过程中,光是解决 KRE 与相关套件的版本不合的问题,就花了我个把小时。所以还是得先提醒一下,目前 ASP.NET vNext 还不是正式版,所以本文的操作步骤与代码不一定符合你的开发环境。 本文范例所使用的开发环境:
小引 上回提到,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)给自带的容器来解析。 自带的 DI 容器支援下列几种生命周期:
接着要来试试把 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>(); } 上面这段代码有几个地方值得注意:
试执行应用程序,结果应该和前一个版本相同。 (注:本文内容将会连同上一集,加以补充完善之后,更新至电子书《.NET 依赖注入》里面。) 参考資料
|
请发表评论