分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

如何在.NET Core控制台程序中使用依赖注入

发布时间:2023-09-06 02:16责任编辑:郭大石关键词:.NET

背景介绍

依赖注入(Dependency Injection), 是面向对象编程中的一种设计原则,可以用来减低代码之间的耦合度。在.NET Core MVC中
我们可以在Startup.cs文件的ConfigureService方法中使用服务容器IServiceCollection注册接口及其实现类的映射。

例如,当我们需要访问Http上下文时,我们需要配置IHttpContextAccessor接口及其实现类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内置的依赖注入模块, 我们创建以下2个服务接口。

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

然后我们针对这2个服务接口,添加2个对应的实现类

 ???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类构造函数依赖了一个IFooService接口的实现
  • FooService类构造函数依赖一个ILoggerFactory接口的实现
  • FooService中,我们输出了一个Information级别的日志

在以上实现类代码中,我们使用了.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>接口的一个实现类,它就是一个.NET Core内置服务容器。
  • 然后我们在服务容器中注册了IFooService接口的实现类FooService以及IBarService接口的实现类BarService
  • 当时需要从服务容器中获取接口类的对应实现类时,我们只需要调用服务容器类的GetSerivce方法。

最终效果

运行程序,我们期望的日志,正确的输出了

info: DIInConsoleApp.Program[0] ?????Start application.info: DIInConsoleApp.FooService[0] ?????Doing the thing 0info: DIInConsoleApp.FooService[0] ?????Doing the thing 1info: DIInConsoleApp.FooService[0] ?????Doing the thing 2info: DIInConsoleApp.FooService[0] ?????Doing the thing 3info: DIInConsoleApp.FooService[0] ?????Doing the thing 4info: DIInConsoleApp.FooService[0] ?????Doing the thing 5info: DIInConsoleApp.FooService[0] ?????Doing the thing 6info: DIInConsoleApp.FooService[0] ?????Doing the thing 7info: DIInConsoleApp.FooService[0] ?????Doing the thing 8info: DIInConsoleApp.FooService[0] ?????Doing the thing 9info: 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方法中配置了接口类及其实现类的自动搜索。这里使用的是一种约定,接口类必须以字母“I”开头, 实现类的名字和接口类只相差一个字母“I”, 例IFooService, FooService, IBarService, BarService
  • 后续代码和前一个例子基本一样。虽然看起来代码多了很多,但是实际上这种使用约定的注入方式非常强力,可以省去很多手动配置的代码。

最终效果

运行程序,代码和之前的效果一样

info: DIInConsoleApp.Program[0] ?????Start application.info: DIInConsoleApp.FooService[0] ?????Doing the thing 0info: DIInConsoleApp.FooService[0] ?????Doing the thing 1info: DIInConsoleApp.FooService[0] ?????Doing the thing 2info: DIInConsoleApp.FooService[0] ?????Doing the thing 3info: DIInConsoleApp.FooService[0] ?????Doing the thing 4info: DIInConsoleApp.FooService[0] ?????Doing the thing 5info: DIInConsoleApp.FooService[0] ?????Doing the thing 6info: DIInConsoleApp.FooService[0] ?????Doing the thing 7info: DIInConsoleApp.FooService[0] ?????Doing the thing 8info: DIInConsoleApp.FooService[0] ?????Doing the thing 9info: DIInConsoleApp.Program[0] ?????All done!

本篇源代码

如何在.NET Core控制台程序中使用依赖注入

原文地址:https://www.cnblogs.com/lwqlun/p/9736391.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved