ASP.NET Core依赖注入解读使用Autofac替代实现
1. 前言
關(guān)于IoC模式(控制反轉(zhuǎn))和DI技術(shù)(依賴注入),我們已經(jīng)見過很多的探討,這里就不再贅述了。比如說必看的Martin Fowler《IoC 容器和 Dependency Injection 模式》,相關(guān)資料鏈接都附于文章末尾。其中我非常贊同Artech的說法"控制更多地體現(xiàn)為一種流程的控制",而依賴注入技術(shù)讓我們的應(yīng)用程序?qū)崿F(xiàn)了松散耦合。
ASP.NET Core本身已經(jīng)集成了一個(gè)輕量級(jí)的IOC容器,開發(fā)者只需要定義好接口后,在Startup.cs的ConfigureServices方法里使用對(duì)應(yīng)生命周期的綁定方法即可,常見方法如下
services.AddTransient<IApplicationService,ApplicationService>services.AddScoped<IApplicationService,ApplicationService>
services.AddSingleton<IApplicationService,ApplicationService>
對(duì)于上述的三種DI注入方式,官方也給出了詳細(xì)的解釋,我來簡(jiǎn)單翻譯一下
Transient
Transient 服務(wù)在每次請(qǐng)求時(shí)被創(chuàng)建,它最好被用于輕量級(jí)無狀態(tài)服務(wù)(如我們的Repository和ApplicationService服務(wù))Scoped
Scoped 服務(wù)在每次請(qǐng)求時(shí)被創(chuàng)建,生命周期橫貫整次請(qǐng)求Singleton
顧名思義,Singleton(單例) 服務(wù)在第一次請(qǐng)求時(shí)被創(chuàng)建(或者當(dāng)我們?cè)贑onfigureServices中指定創(chuàng)建某一實(shí)例并運(yùn)行方法),其后的每次請(qǐng)求將沿用已創(chuàng)建服務(wù)。如果開發(fā)者的應(yīng)用需要單例服務(wù)情景,請(qǐng)?jiān)O(shè)計(jì)成允許服務(wù)容器來對(duì)服務(wù)生命周期進(jìn)行操作,而不是手動(dòng)實(shí)現(xiàn)單例設(shè)計(jì)模式然后由開發(fā)者在自定義類中進(jìn)行操作。
在這之后,我們便可以將服務(wù)通過構(gòu)造函數(shù)注入或者是屬性注入的方式注入到Controller,View(通過使用@inject),甚至是Filter中(以前使用Unity將依賴注入到Filter真是一種痛苦)。話不多說,先來體驗(yàn)一把
Tips:Startup.cs是什么,詳見ASP.NET Core 介紹和項(xiàng)目解讀
2. ASP.NET Core 中的DI方式
大多項(xiàng)目舉例依賴注入的生命周期演示時(shí),都會(huì)采取可變Guid來作為返回顯示,此次示例也會(huì)這樣處理。我們先定義一個(gè)IGuidAppService接口,里面定義基接口和三種注入模式的接口
? ?public interface IGuidAppService{ ? ? ?? ? ? ? ?Guid GuidItem(); ? ?} ?
?
? ? public interface IGuidTransientAppService : IGuidAppService ? ?{ ? ?} ?
? ?
? ??public interface IGuidScopedAppService : IGuidAppService ? ?{ ? ?} ?
? ??public interface IGuidSingletonAppService : IGuidAppService ? ?{ ? ?}
同樣的,在GuidAppService中定義其實(shí)現(xiàn)類。這里為了直觀顯示每次請(qǐng)求的返回值,采取如下代碼
? ?public class GuidAppServiceBase : IGuidAppService ? ?{ ? ?? ? ?? ??private readonly Guid _item; ? ? ?
? ? ? ? ?
? ? ? ? ? public GuidAppServiceBase() ? ? ? ?{ ? ? ? ? ? ?_item = Guid.NewGuid(); ? ? ? ?} ? ? ?
? ? ? ? ?
? ? ? ? ??public Guid GuidItem() ? ? ? ?{ ? ? ? ?
? ? ? ? ? ? ? ?return _item; ? ? ? ?} ? ?} ? ? ? ?public class GuidTransientAppService : GuidAppServiceBase, IGuidTransientAppService ? ?{ ? ?} ? ? ? ?public class GuidScopedAppService : GuidAppServiceBase, IGuidScopedAppService ? ?{ ? ?} ? ?public class GuidSingletonAppService : GuidAppServiceBase, IGuidSingletonAppService ? ?{ ? ?}
最后是Controller和View視圖的代碼
? ?之后我們打開兩個(gè)瀏覽器,分別刷新數(shù)次,也只會(huì)發(fā)現(xiàn)“TransientItem”和“ScopedItem”的數(shù)值不斷變化,“SingletonItem”欄的數(shù)值是不會(huì)有任何變化的,這就體現(xiàn)出單例模式的作用了,示例圖如下
但是這好像還不夠,要知道我們的Scoped的解讀是“生命周期橫貫整次請(qǐng)求”,但是現(xiàn)在演示起來和Transient好像沒有什么區(qū)別(因?yàn)閮蓚€(gè)頁面每次瀏覽器請(qǐng)求仍然是獨(dú)立的,并不包含于一次中),所以我們采用以下代碼來演示下(同一請(qǐng)求源)
依然是 Ctrl+F5 調(diào)試運(yùn)行,可以發(fā)現(xiàn)“ScopedItem”在同一請(qǐng)求源中是不會(huì)發(fā)生變化的,但是“TransientItem”依然不斷變化,理論仍然是支持的
3. Autofac實(shí)現(xiàn)和自定義實(shí)現(xiàn)擴(kuò)展方法
除了ASP.NETCore自帶的IOC容器外,我們還可以使用其他成熟的DI框架,如Autofac,StructureMap等(筆者只用過Unity,Ninject和Castle,Castle也是使用ABP時(shí)自帶的)。
3.1 安裝Autofac
首先在project.json的dependency節(jié)點(diǎn)中加入Autofac.Extensions.DependencyInjection引用,目前最新版本是4.0.0-rc3-309
3.2 創(chuàng)建容器并注冊(cè)依賴
在Startup.cs中創(chuàng)建一個(gè)public IContainer ApplicationContainer?{?
get; private set;
?}
對(duì)象,并把ConfigureServices返回類型改為IServiceProvider,然后復(fù)制以下代碼進(jìn)去,也可以實(shí)現(xiàn)相關(guān)功能
var builder = new ContainerBuilder();//注意以下寫法 builder.RegisterType<GuidTransientAppService>().As<IGuidTransientAppService>(); builder.RegisterType<GuidScopedAppService>().As<IGuidScopedAppService>().InstancePerLifetimeScope(); builder.RegisterType<GuidSingletonAppService>().As<IGuidSingletonAppService>().SingleInstance(); builder.Populate(services); this.ApplicationContainer = builder.Build();return new AutofacServiceProvider(this.ApplicationContainer);值得注意的幾點(diǎn):
創(chuàng)建Autofac容器時(shí)不要忘了將ConfigureServices的返回值修改為IServiceProvider
對(duì)應(yīng)ASP.NET Core提及的不同的生命周期,Autofac也定義了對(duì)應(yīng)的擴(kuò)展方法,如InstancePerLifetimeScope等,默認(rèn)為Transient模式,包括EntityFramwork等Context也是該種模式
Autofac Core不支持從View中注入,但是可以和ASP.NET Core自帶IOC容器配合使用
Autofac Core版本和傳統(tǒng)的ASP.NET MVC項(xiàng)目版本的區(qū)別
4. 參考鏈接
IoC 容器和 Dependency Injection 模式
控制反轉(zhuǎn)—維基百科
DependencyInjection-GitHub
ASP.NET Core中的依賴注入(4): 構(gòu)造函數(shù)的選擇與服務(wù)生命周期管理
Dependency Injectionf!
原文地址:http://www.cnblogs.com/wangpd/p/7568451.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core依赖注入解读使用Autofac替代实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: .NET Conf 2017后初尝Xam
- 下一篇: C#中的两把双刃剑:抽象类和接口