一起聊聊Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.DependencyInjection在github上同樣是開(kāi)源的,它在dotnetcore里被廣泛的使用,比起之前的autofac,unity來(lái)說(shuō),它可以說(shuō)是個(gè)包裹,或者叫適配器,它自己提供了默認(rèn)的DI實(shí)現(xiàn),同時(shí)也支持第三方的IOC容器,在這段時(shí)間里使用了它,就想,這東西為什么被在dotnetcore里大放異彩?為什么會(huì)全程使用它?從程序的開(kāi)始到程序啟動(dòng)起來(lái),你可以發(fā)現(xiàn)它無(wú)處不在,在框架里是這樣,在業(yè)務(wù)層同時(shí)也是這樣。
聊聊Microsoft.Extensions.DependencyInjection知識(shí)點(diǎn)包括
它的開(kāi)源地址
IServiceCollection和IApplicationBuilder
自定義模塊用它
在Startup.ConfigureServices中注冊(cè)自定義模塊
在Startup.Configure中使用它,進(jìn)行默認(rèn)模塊的初始化
在任意對(duì)象的構(gòu)造方法中使用它
一步一步的揭秘
一 它的開(kāi)源地址
https://github.com/aspnet/DependencyInjection
可以看看它的README.md,就知道它是個(gè)大包裹,類似于大叔LindAgile里的Container,完全可以擴(kuò)展支持其它第三方的IOC容器,這就像大叔經(jīng)常說(shuō)的那句話一樣,在IT江湖中,英雄總是所風(fēng)略同……
二 dotnetcore整個(gè)框架在用它
在你的dotnetcore應(yīng)用程序里,你會(huì)發(fā)現(xiàn)在Startup類中有很多像services.AddMvc()這樣的方法,這實(shí)質(zhì)是像應(yīng)用程序中注冊(cè)一個(gè)組件,這里的MVC是一個(gè)統(tǒng)一的組件,它不依賴于windows,不依賴于dotnet,整個(gè)dotnetcore里把很多組件都解耦了,這樣在維護(hù)和nuget包升級(jí)時(shí)都更靈活,自己有問(wèn)題就優(yōu)化自己,而不影響其它模塊。(越說(shuō)越像微服務(wù)的宗旨)。
IServiceCollection主要用來(lái)注冊(cè)服務(wù),就是某個(gè)接口和某種實(shí)現(xiàn)的對(duì)應(yīng)關(guān)系,這種注冊(cè)是我們?cè)赟tartup.ConfigureServices方法里完成的,如下面的AddLind()這個(gè)方法,它完成了對(duì)Lind模塊的注冊(cè),在方法內(nèi)部可以注冊(cè)本模塊的其它服務(wù)。
? ?? ?/// </summary>/// <param name="services"></param>/// <param name="setupAction"></param>/// <returns></returns>public static LindBuilder AddLind( ? ? ?
? ? ?this IServiceCollection services,Action<LindOptions> setupAction){ ? ? ? ? ?
??if (setupAction == null) throw new ArgumentNullException(nameof(setupAction));services.Configure(setupAction); ? ? ?
?? ? ?var options = new LindOptions(); ? ? ? ? ?
??//注冊(cè)框架所依賴的基礎(chǔ)模塊 ? ? ? ? ? ?//options.Extensions.Add(); ? ? ? ? ?
?//注冊(cè)外部模塊 ? ? ? ? ?
? ? ? ? ? ?setupAction(options); ? ? ? ?
? ? ? ? ? ??foreach (var serviceExtension in options.Extensions)serviceExtension.AddServices(services);services.AddSingleton(options); ? ?
? ? ? ?return new LindBuilder(services);}
IApplicationBuilder是指對(duì)應(yīng)該程序的啟動(dòng),或者理解為初始化,當(dāng)上面的服務(wù)注冊(cè)完成后就執(zhí)行它了,我們一般在Startup.Configure去激活它,它的目的比較單純,就是對(duì)模塊進(jìn)行初始化,如果沒(méi)什么特殊的功能,這個(gè)代碼可以是空的,下面Builder中初始化了日志組件。
? ? ? ?/// </summary>/// <param name="app">The <see cref="IApplicationBuilder" /> instance this method extends.</param>/// <returns>The <see cref="IApplicationBuilder" /> instance this method extends.</returns>public static IApplicationBuilder UseLind(this IApplicationBuilder app){ ? ? ? ? ?
??if (app == null) ? ? ? ? ?
? ? ?throw new ArgumentNullException(nameof(app)); ? ? ? ? ? ?var provider = app.ApplicationServices; ?
? ? ? ? ?//注冊(cè)Lind框架所需要的底層服務(wù)LoggerFactory.SetLogger((ILogger)provider.GetService(typeof(ILogger))); ? ? ? ? ? ?return app;}
三 自定義模塊用它
如果希望定義自己的功能模塊實(shí)現(xiàn)與dotnetcore框架的結(jié)合可以自定義Options和OptionsExtensions,前者主要實(shí)現(xiàn)的是服務(wù)列表的注冊(cè),而后臺(tái)主要是對(duì)現(xiàn)有模塊提供注冊(cè)的入口,下面的代碼主要實(shí)現(xiàn)了一個(gè)EF倉(cāng)儲(chǔ)模塊的注冊(cè)過(guò)程。
模塊所需的模型
public class RepositoryOptions{ ? ? ? ?public string ConnString { get; set; }}注冊(cè)服務(wù)列表
? ?/// </summary>public class EFOptionsExtension : ILindOptionsExtension{ ? ? ?
? ? ??private readonly Action<RepositoryOptions> _configure; ? ? ? ? ?public EFOptionsExtension(Action<RepositoryOptions> configure){_configure = configure;} ? ? ?
?public void AddServices(IServiceCollection services){services.AddSingleton(typeof(IRepository), typeof(EFRepository)); ? ? ? ?
? ?var mysqlOptions = new RepositoryOptions();_configure(mysqlOptions);}}
在外部使用這個(gè)模塊,就是在Startup中注冊(cè)它
public static class RepositoryOptionsExtensions{ ? ? ?? ? ??public static LindOptions UseEF(this LindOptions options, Action<RepositoryOptions> configure){options.RegisterExtension(new EFOptionsExtension(configure)); ? ? ?
? ? ? ? ?return options;}}
四 在Startup.ConfigureServices中注冊(cè)自定義模塊
上面的代碼主要是自定義一個(gè)模塊,而在startup中使用它,就像下面的代碼,十分簡(jiǎn)潔,當(dāng)前有些配置信息可以到在基于環(huán)境變量的json文件里!
public void ConfigureServices(IServiceCollection services){services.AddMvc();services.AddLind(x =>{x.UseEF(o =>{o.ConnString = "localhost:1433";});x.UseDapper(o =>{o.ConnString = "localhost:3306";});});}五 在Startup.Configure中使用它,進(jìn)行默認(rèn)模塊的初始化
上面的代碼實(shí)現(xiàn)了對(duì)模塊下一些服務(wù)進(jìn)行注冊(cè),然后下面代碼主要是進(jìn)行一些初始化的工作。
public void Configure(IApplicationBuilder app, IHostingEnvironment env){ ? ? ? ? ? ?if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UseMvc();app.UseLind();}六 在任意對(duì)象的構(gòu)造方法中使用它
當(dāng)我們把服務(wù)注冊(cè)后,可以在任意類型的構(gòu)造方法中使用它,而不是只能在控制器中使用,這一點(diǎn)dotnetcore DI做的確實(shí)不錯(cuò),給它100個(gè)贊!
這種注冊(cè)
? ?public class ApiLoggerOptionsExtension : IPilipaOptionsExtension{Action<ApiLoggerConfig> _config; ? ? ???public ApiLoggerOptionsExtension(Action<ApiLoggerConfig> config){_config = config;} ? ?
??public void AddServices(IServiceCollection services){ApiLoggerConfig apiLoggerConfig = new ApiLoggerConfig();_config(apiLoggerConfig);//裝飾services.AddSingleton(apiLoggerConfig);//注冊(cè)對(duì)象里的屬性,在對(duì)象的構(gòu)造方法被注入services.AddSingleton(typeof(ILogger), typeof(ApiLogger));//注冊(cè)對(duì)象,在使用對(duì)象的類的構(gòu)造方法被注入 ? ? ? ?}}
這種使用
? ? ? ?ApiLoggerConfig _config; ?? ? ? ?
? ? ? ?public ApiLogger(ApiLoggerConfig config){_config = config;}
對(duì)于上面的代碼實(shí)現(xiàn)了在OptionsExtension里進(jìn)行注冊(cè),然后在任意類型中使用它,感覺(jué)這點(diǎn)確實(shí)靈活了不少!
今天咱們對(duì)dotnetcore DependencyInjection的分享就到這里,希望大家也盡量把模塊從項(xiàng)目中解放出來(lái)!
原文地址:?http://www.cnblogs.com/lori/p/7651787.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺(tái)或掃描二維碼關(guān)注
總結(jié)
以上是生活随笔為你收集整理的一起聊聊Microsoft.Extensions.DependencyInjection的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ASP.NET Core 2.0 支付宝
- 下一篇: 【杭州】Hack for Cloud B