如何在.NET Core控制台程序中使用依赖注入
背景介绍
依赖注入(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控制台程序中使用依赖注入的更多相关文章
- 在.NET Core控制台程序中使用依赖注入
之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ...
- ASP.NET Core - 在ActionFilter中使用依赖注入
上次ActionFilter引发的一个EF异常,本质上是对Core版本的ActionFilter的知识掌握不够牢固造成的,所以花了点时间仔细阅读了微软的官方文档.发现除了IActionFilter.I ...
- dotnet core在Task中使用依赖注入的Service/EFContext
C#:在Task中使用依赖注入的Service/EFContext dotnet core时代,依赖注入基本已经成为标配了,这就不多说了. 前几天在做某个功能的时候遇到在Task中使用EF DbCon ...
- 如何在 ASP.Net Web Forms 中使用依赖注入
依赖注入技术就是将一个对象注入到一个需要它的对象中,同时它也是控制反转的一种实现,显而易见,这样可以实现对象之间的解耦并且更方便测试和维护,依赖注入的原则早已经指出了,应用程序的高层模块不依赖于低层模 ...
- .net core控制台程序中使用原生依赖注入
如果要在程序中使用DbContext,则需要先在Nuget中安装Microsoft.EntityFrameworkCore.SqlServer using ConsoleApp1.EntityFram ...
- ASP.NET Core 新建线程中使用依赖注入的问题
问题来自博问的一个提问 .net core 多线程数据保存的时候DbContext被释放 . TCPService 通过构造函数注入了 ContentService , ContentService ...
- .NET CORE——Console中使用依赖注入
我们都知道,在 ASP.NET CORE 中通过依赖注入的方式来使用服务十分的简单,而在 Console 中,其实也只是稍微绕了个小弯子而已.不管是内置 DI 组件或者第三方的 DI 组件(如Auto ...
- ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings,及.NET Core控制台项目中读取AppSettings
问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...
- 大比速: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提供了众多的远程服务形式.在只 ...
随机推荐
- Exp1 PC平台逆向破解 20165235 祁瑛
Exp1 PC平台逆向破解 20165235 祁瑛 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件.该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字 ...
- 日常报错记录4:ssh工程复制粘贴顺序。
今天要复制一个项目. 久久不能如愿. web.xml里面老是有红的,比如applicationContext.xml字段. 它应该是web.xml要找它,于是,我先把applicationContex ...
- POJ 3751 JAVA
题意: 对于给定的采用”yyyy/mm/dd”加24小时制(用短横线”-”连接)来表示日期和时间的字符串, 请编程实现将其转换成”mm/dd/yyyy”加12小时制格式的字符串,末尾加上pm或者am. ...
- 【转发】如何使用NPM?CNPM又是什么?
转发:https://www.jianshu.com/p/f581cf9360a2 背景介绍 什么是npm? npm(node package manager)是nodejs的包管理器,用于node插 ...
- BZOJ.5397.circular(随机化 贪心)
BZOJ 感觉自己完全没做过环上选线段的问题(除了一个2-SAT),所以来具体写一写qwq. 基本完全抄自remoon的题解qwq... (下标从\(0\sim m-1\)) 拆环为链,对于原线段\( ...
- ZOJ4043 : Virtual Singers
将所有$A$和$B$混在一起排序,那么每个$B$要匹配一个$A$,从左往右依次考虑每个数: 如果是一个$B$: 如果左边没有多余的$A$,那么将其放入堆$q_C$中,表示这个$B$还未匹配. 否则选择 ...
- 微信跳转技术,浏览器唤起微信,weixin://dl/business/?ticket=
weixin://dl/business/?ticket= 到底怎么生成的?调用以下接口 weixin://dl/scan 扫一扫weixin://dl/feedback 反馈weixin://dl ...
- 关于A2C算法
https://github.com/sweetice/Deep-reinforcement-learning-with-pytorch/blob/master/Char4%20A2C/A2C.py ...
- IOS开发中关于runtime的认识
首先要知道我们写的代码在程序运行过程中都会被转化成runtime的C代码执行. runtime突出的一点就是OC中消息传递机制的应用.objc_msgsend(target,SEL); 首先我们先看一 ...
- remote: HTTP Basic: Access denied fatal: Authentication failed for'https'
问题原因: 重置了密码导致git操作失败. 解决方案: 输入:git config --system --unset credential.helper 再次进行git操作,输入用户名,密码.