溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

在.NET Core控制臺(tái)程序中使用依賴注入的案例

發(fā)布時(shí)間:2021-02-07 13:48:15 來(lái)源:億速云 閱讀:326 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下在.NET Core控制臺(tái)程序中使用依賴注入的案例,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

背景介紹

Dependency Injection:又稱依賴注入,簡(jiǎn)稱DI。在以前的開發(fā)方式中,層與層之間、類與類之間都是通過(guò)new一個(gè)對(duì)方的實(shí)例進(jìn)行相互調(diào)用,這樣在開發(fā)過(guò)程中有一個(gè)好處,可以清晰的知道在使用哪個(gè)具體的實(shí)現(xiàn)。隨著軟件體積越來(lái)越龐大,邏輯越來(lái)越復(fù)雜,當(dāng)需要更換實(shí)現(xiàn)方式,或者依賴第三方系統(tǒng)的某些接口時(shí),這種相互之間持有具體實(shí)現(xiàn)的方式不再合適。為了應(yīng)對(duì)這種情況,就要采用契約式編程:相互之間依賴于規(guī)定好的契約(接口),不依賴于具體的實(shí)現(xiàn)。這樣帶來(lái)的好處是相互之間的依賴變得非常簡(jiǎn)單,又稱松耦合。至于契約和具體實(shí)現(xiàn)的映射關(guān)系,則會(huì)通過(guò)配置的方式在程序啟動(dòng)時(shí)由運(yùn)行時(shí)確定下來(lái)。這就會(huì)用到DI。

依賴注入(Dependency Injection), 是面向?qū)ο缶幊讨械囊环N設(shè)計(jì)原則,可以用來(lái)減低代碼之間的耦合度。在.NET Core MVC中

我們可以在Startup.cs文件的ConfigureService方法中使用服務(wù)容器IServiceCollection注冊(cè)接口及其實(shí)現(xiàn)類的映射。

例如,當(dāng)我們需要訪問(wèn)Http上下文時(shí),我們需要配置IHttpContextAccessor接口及其實(shí)現(xiàn)類HttpContextAccessor

 public void ConfigureServices(IServiceCollection services)
 {
 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
 }

那么當(dāng)我們編寫一個(gè).NET Core控制臺(tái)程序的時(shí)候,我們?cè)撊绾问褂靡蕾囎⑷肽兀?/p>

使用內(nèi)置依賴注入

在.NET Core中,內(nèi)置依賴注入模塊使用的程序集是Microsoft.Extensions.DependencyInjection。

所以如果希望在控制臺(tái)程序中使用內(nèi)置依賴注入,我們首先需要使用NUGET添加對(duì)Microsoft.Extensions.DependencyInjection程序集的引用。

PM> Install-Package Microsoft.Extensions.DependencyInjection

這里為了說(shuō)明如何使用.NET Core內(nèi)置的依賴注入模塊, 我們創(chuàng)建以下2個(gè)服務(wù)接口。

 public interface IFooService
 {
 void DoThing(int number);
 }

 public interface IBarService
 {
 void DoSomeRealWork();
 }

然后我們針對(duì)這2個(gè)服務(wù)接口,添加2個(gè)對(duì)應(yīng)的實(shí)現(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類構(gòu)造函數(shù)依賴了一個(gè)IFooService接口的實(shí)現(xiàn)

  • FooService類構(gòu)造函數(shù)依賴一個(gè)ILoggerFactory接口的實(shí)現(xiàn)

  • FooService中,我們輸出了一個(gè)Information級(jí)別的日志

在以上實(shí)現(xiàn)類代碼中,我們使用了.NET Core內(nèi)置的日志模塊, 所以我們還需要使用NUGET添加對(duì)應(yīng)的程序集Microsoft.Extensions.Logging.Console

PM> Install-Package Microsoft.Extensions.Logging.Console

最后我們來(lái)修改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!");

 }
 }

代碼解釋

  • 這里我們手動(dòng)實(shí)例化了一個(gè)ServiceCollection類, 這個(gè)類是IServiceCollection>接口的一個(gè)實(shí)現(xiàn)類,它就是一個(gè).NET Core內(nèi)置服務(wù)容器。

  • 然后我們?cè)诜?wù)容器中注冊(cè)了IFooService接口的實(shí)現(xiàn)類FooService以及IBarService接口的實(shí)現(xiàn)類BarService。

  • 當(dāng)時(shí)需要從服務(wù)容器中獲取接口類的對(duì)應(yīng)實(shí)現(xiàn)類時(shí),我們只需要調(diào)用服務(wù)容器類的GetSerivce方法。

最終效果

運(yùn)行程序,我們期望的日志,正確的輸出了

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!

使用第三方依賴注入

除了使用內(nèi)置的依賴注入模塊,我們還可以直接使用一些第三方的依賴注入框架,例如Autofac, StructureMap。

這里我們來(lái)使用StructureMap來(lái)替換當(dāng)前的內(nèi)置的依賴注入框架。

首先我們需要先添加程序集引用。

PM> Install-Package StructureMap.Microsoft.DependencyInjection

然后我們來(lái)修改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();
 }
 }
}

代碼解釋

  • 這里我們實(shí)例化了一個(gè)StructureMap的服務(wù)容器Container, 并在其Configure方法中配置了接口類及其實(shí)現(xiàn)類的自動(dòng)搜索。這里使用的是一種約定,接口類必須以字母“I”開頭, 實(shí)現(xiàn)類的名字和接口類只相差一個(gè)字母“I”, 例IFooService, FooService, IBarService, BarService

  • 后續(xù)代碼和前一個(gè)例子基本一樣。雖然看起來(lái)代碼多了很多,但是實(shí)際上這種使用約定的注入方式非常強(qiáng)力,可以省去很多手動(dòng)配置的代碼。

最終效果

運(yùn)行程序,代碼和之前的效果一樣

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 Core控制臺(tái)程序中使用依賴注入的案例”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI