在.NET Core控制臺程序中如何使用依賴注入詳解
背景介紹
Dependency Injection:又稱依賴注入,簡稱DI。在以前的開發(fā)方式中,層與層之間、類與類之間都是通過new一個對方的實例進行相互調用,這樣在開發(fā)過程中有一個好處,可以清晰的知道在使用哪個具體的實現(xiàn)。隨著軟件體積越來越龐大,邏輯越來越復雜,當需要更換實現(xiàn)方式,或者依賴第三方系統(tǒng)的某些接口時,這種相互之間持有具體實現(xiàn)的方式不再合適。為了應對這種情況,就要采用契約式編程:相互之間依賴于規(guī)定好的契約(接口),不依賴于具體的實現(xiàn)。這樣帶來的好處是相互之間的依賴變得非常簡單,又稱松耦合。至于契約和具體實現(xiàn)的映射關系,則會通過配置的方式在程序啟動時由運行時確定下來。這就會用到DI。
依賴注入(Dependency Injection), 是面向對象編程中的一種設計原則,可以用來減低代碼之間的耦合度。在.NET Core MVC中
我們可以在Startup.cs文件的ConfigureService方法中使用服務容器IServiceCollection注冊接口及其實現(xiàn)類的映射。
例如,當我們需要訪問Http上下文時,我們需要配置IHttpContextAccessor接口及其實現(xiàn)類HttpContextAccessor
public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); }
那么當我們編寫一個.NET Core控制臺程序的時候,我們該如何使用依賴注入呢?
使用內置依賴注入
在.NET Core中,內置依賴注入模塊使用的程序集是Microsoft.Extensions.DependencyInjection
。
所以如果希望在控制臺程序中使用內置依賴注入,我們首先需要使用NUGET添加對Microsoft.Extensions.DependencyInjection
程序集的引用。
PM> Install-Package Microsoft.Extensions.DependencyInjection
這里為了說明如何使用.NET Core內置的依賴注入模塊, 我們創(chuàng)建以下2個服務接口。
public interface IFooService { void DoThing(int number); } public interface IBarService { void DoSomeRealWork(); }
然后我們針對這2個服務接口,添加2個對應的實現(xiàn)類
public class BarService : IBarService { private readonly IFooService _fooService; public BarService(IFooService fooService) { _fooService = fooService; } public void DoSomeRealWork() { for (int i = 0; i < 10; i++) { _fooService.DoThing(i); } } } public class FooService : IFooService { private readonly ILogger<FooService> _logger; public FooService(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger<FooService>(); } public void DoThing(int number) { _logger.LogInformation($"Doing the thing {number}"); } }
代碼解釋
- BarService類構造函數(shù)依賴了一個IFooService接口的實現(xiàn)
- FooService類構造函數(shù)依賴一個ILoggerFactory接口的實現(xiàn)
- FooService中,我們輸出了一個Information級別的日志
在以上實現(xiàn)類代碼中,我們使用了.NET Core內置的日志模塊, 所以我們還需要使用NUGET添加對應的程序集Microsoft.Extensions.Logging.Console
PM> Install-Package Microsoft.Extensions.Logging.Console
最后我們來修改Program.cs, 代碼如下
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; public class Program { public static void Main(string[] args) { //setup our DI var serviceProvider = new ServiceCollection() .AddLogging() .AddSingleton<IFooService, FooService>() .AddSingleton<IBarService, BarService>() .BuildServiceProvider(); //configure console logging serviceProvider .GetService<ILoggerFactory>() .AddConsole(LogLevel.Debug); var logger = serviceProvider.GetService<ILoggerFactory>() .CreateLogger<Program>(); logger.LogInformation("Starting application"); //do the actual work here var bar = serviceProvider.GetService<IBarService>(); bar.DoSomeRealWork(); logger.LogInformation("All done!"); } }
代碼解釋
- 這里我們手動實例化了一個ServiceCollection類, 這個類是IServiceCollection>接口的一個實現(xiàn)類,它就是一個.NET Core內置服務容器。
- 然后我們在服務容器中注冊了IFooService接口的實現(xiàn)類FooService以及IBarService接口的實現(xiàn)類BarService。
- 當時需要從服務容器中獲取接口類的對應實現(xiàn)類時,我們只需要調用服務容器類的GetSerivce方法。
最終效果
運行程序,我們期望的日志,正確的輸出了
info: DIInConsoleApp.Program[0]
Start application.
info: DIInConsoleApp.FooService[0]
Doing the thing 0
info: DIInConsoleApp.FooService[0]
Doing the thing 1
info: DIInConsoleApp.FooService[0]
Doing the thing 2
info: DIInConsoleApp.FooService[0]
Doing the thing 3
info: DIInConsoleApp.FooService[0]
Doing the thing 4
info: DIInConsoleApp.FooService[0]
Doing the thing 5
info: DIInConsoleApp.FooService[0]
Doing the thing 6
info: DIInConsoleApp.FooService[0]
Doing the thing 7
info: DIInConsoleApp.FooService[0]
Doing the thing 8
info: DIInConsoleApp.FooService[0]
Doing the thing 9
info: DIInConsoleApp.Program[0]
All done!
使用第三方依賴注入
除了使用內置的依賴注入模塊,我們還可以直接使用一些第三方的依賴注入框架,例如Autofac, StructureMap。
這里我們來使用StructureMap來替換當前的內置的依賴注入框架。
首先我們需要先添加程序集引用。
PM> Install-Package StructureMap.Microsoft.DependencyInjection
然后我們來修改Program.cs文件,代碼如下
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using StructureMap; using System; namespace DIInConsoleApp { class Program { static void Main(string[] args) { var services = new ServiceCollection().AddLogging(); var container = new Container(); container.Configure(config => { config.Scan(_ => { _.AssemblyContainingType(typeof(Program)); _.WithDefaultConventions(); }); config.Populate(services); }); var serviceProvider = container.GetInstance<IServiceProvider>(); serviceProvider.GetService<ILoggerFactory>().AddConsole(LogLevel.Debug); var logger = serviceProvider.GetService<ILoggerFactory>().CreateLogger<Program>(); logger.LogInformation("Start application."); var bar = serviceProvider.GetService<IBarService>(); bar.DoSomeRealWork(); logger.LogInformation("All done!"); Console.Read(); } } }
代碼解釋
- 這里我們實例化了一個StructureMap的服務容器Container, 并在其Configure方法中配置了接口類及其實現(xiàn)類的自動搜索。這里使用的是一種約定,接口類必須以字母“I”開頭, 實現(xiàn)類的名字和接口類只相差一個字母“I”, 例IFooService, FooService, IBarService, BarService
- 后續(xù)代碼和前一個例子基本一樣。雖然看起來代碼多了很多,但是實際上這種使用約定的注入方式非常強力,可以省去很多手動配置的代碼。
最終效果
運行程序,代碼和之前的效果一樣
info: DIInConsoleApp.Program[0]
Start application.
info: DIInConsoleApp.FooService[0]
Doing the thing 0
info: DIInConsoleApp.FooService[0]
Doing the thing 1
info: DIInConsoleApp.FooService[0]
Doing the thing 2
info: DIInConsoleApp.FooService[0]
Doing the thing 3
info: DIInConsoleApp.FooService[0]
Doing the thing 4
info: DIInConsoleApp.FooService[0]
Doing the thing 5
info: DIInConsoleApp.FooService[0]
Doing the thing 6
info: DIInConsoleApp.FooService[0]
Doing the thing 7
info: DIInConsoleApp.FooService[0]
Doing the thing 8
info: DIInConsoleApp.FooService[0]
Doing the thing 9
info: DIInConsoleApp.Program[0]
All done!
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關文章
詳解.Net core2.0日志組件Log4net、Nlog簡單性能測試
這篇文章主要介紹了詳解.Net core2.0日志組件Log4net、Nlog簡單性能測試,比較log4net、nlog的文件寫入性能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-07-07解決uploadify使用時session發(fā)生丟失問題的方法
這篇文章主要為大家詳細介紹了uploadify使用時發(fā)現(xiàn)session發(fā)生丟失問題的解決方法,遇到過類似問題的朋友可以參考本文進行解決2016-05-05利用Service Fabric承載eShop On Containers的實現(xiàn)方法
下面小編就為大家分享一篇利用Service Fabric承載eShop On Containers的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01