背景介绍

依赖注入(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 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方法中配置了接口类及其实现类的自动搜索。这里使用的是一种约定,接口类必须以字母“I”开头, 实现类的名字和接口类只相差一个字母“I”, 例IFooService, FooService, IBarService, BarService
  • 后续代码和前一个例子基本一样。虽然看起来代码多了很多,但是实际上这种使用约定的注入方式非常强力,可以省去很多手动配置的代码。

最终效果

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

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控制台程序中使用依赖注入的更多相关文章

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

    之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ...

  2. ASP.NET Core - 在ActionFilter中使用依赖注入

    上次ActionFilter引发的一个EF异常,本质上是对Core版本的ActionFilter的知识掌握不够牢固造成的,所以花了点时间仔细阅读了微软的官方文档.发现除了IActionFilter.I ...

  3. dotnet core在Task中使用依赖注入的Service/EFContext

    C#:在Task中使用依赖注入的Service/EFContext dotnet core时代,依赖注入基本已经成为标配了,这就不多说了. 前几天在做某个功能的时候遇到在Task中使用EF DbCon ...

  4. 如何在 ASP.Net Web Forms 中使用依赖注入

    依赖注入技术就是将一个对象注入到一个需要它的对象中,同时它也是控制反转的一种实现,显而易见,这样可以实现对象之间的解耦并且更方便测试和维护,依赖注入的原则早已经指出了,应用程序的高层模块不依赖于低层模 ...

  5. .net core控制台程序中使用原生依赖注入

    如果要在程序中使用DbContext,则需要先在Nuget中安装Microsoft.EntityFrameworkCore.SqlServer using ConsoleApp1.EntityFram ...

  6. ASP.NET Core 新建线程中使用依赖注入的问题

    问题来自博问的一个提问 .net core 多线程数据保存的时候DbContext被释放 . TCPService 通过构造函数注入了 ContentService , ContentService ...

  7. .NET CORE——Console中使用依赖注入

    我们都知道,在 ASP.NET CORE 中通过依赖注入的方式来使用服务十分的简单,而在 Console 中,其实也只是稍微绕了个小弯子而已.不管是内置 DI 组件或者第三方的 DI 组件(如Auto ...

  8. ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings,及.NET Core控制台项目中读取AppSettings

    问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...

  9. 大比速:remoting、WCF(http)、WCF(tcp)、WCF(RESTful)、asp.net core(RESTful) .net core 控制台程序使用依赖注入(Autofac)

    大比速:remoting.WCF(http).WCF(tcp).WCF(RESTful).asp.net core(RESTful) 近来在考虑一个服务选型,dotnet提供了众多的远程服务形式.在只 ...

随机推荐

  1. 动态网页获取ajax,post方法,url里面不直接显示参数

    记录一下,爬去ajax数据时,需要注意一下是post方法还是get方法,get方法就正常做就行了,但是post方法的话,需要这样,如下 a = requests.request('post',url) ...

  2. twig模板的进一步学习以及在symfony当中的使用

    首先,twig可以理解为用于输出html代码的,虽然用PHP等其他语言也可以输出,但是twig更为简洁高效,同时twig模板被编译成原生的php类缓存起来,所以才会这么快, 其实twig跟php类差不 ...

  3. pycharm中range的应用

    v = range(100) for item in v: print (item) #输出结果是0 1 2 3 ......99 这是在python3中实现的,python2中不一样 下面是一个从大 ...

  4. 初学笔记之:Java_Script的for循环事件绑定

    看JS,一直纠结于for循环事件绑定,我一直不理解,想找到一些解释,以下是个人研究一个下午后的一些见解,有不对的还望大神们指正,轻喷.在这里谢过啦. 首先,目的是做一个滑动切换图片的效果,上JS代码: ...

  5. Git ignore文件的用法

    这周为了往自己个人代码仓库里囤货,把在公司写的一些东西上传到了自己的GitHub代码仓库,手抖把测试用的日志也一并上传了.上传没多长时间就被运维找上门了,说commit里包含内网相关信息,要求删除.当 ...

  6. PBRT笔记(6)——采样和重构

    前言 本文仅作为个人笔记分享,又因为本章涉及多个专业领域而本人皆未接触过,所以难免出错,请各位读者注意. 对于数字图像需要区分image pixels(特定采样处的函数值)和display pixel ...

  7. 使用bootstrap本机调试时,应该使用本地服务器地址访问,如http://192.168.19.112/rjshop/,否则360浏览器会出现不兼容的情况

    使用bootstrap本机调试时,应该使用本地服务器地址访问,如http://192.168.19.112/rjshop/,否则360浏览器会出现不兼容的情况

  8. 关于A2C算法

    https://github.com/sweetice/Deep-reinforcement-learning-with-pytorch/blob/master/Char4%20A2C/A2C.py ...

  9. centos为docker配置加速器

    国内拉去docker镜像慢得可怜,为了解决这个问题,可为docker配置加速器. 1.修改daemon配置文件 sudo mkdir -p /etc/dockervim /etc/docker/dae ...

  10. vbs编写一个函数,将1001到1050(50串数字)读入test.txt文件。每串数字占一行,不是覆盖。

    Option Explicit---------------------------------------------------------开头 dim fas,objfso,printstr,o ...