在.NET Core控制台程序中如何使用依赖注入详解
 更新时间:2018年10月11日 10:34:08   作者:LamondLu  

这篇文章主要给大家介绍了关于在.NET Core控制台程序中如何使用依赖注入的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧

背景介绍

Dependency Injection:又称依赖注入,简称DI。在以前的开发方式中,层与层之间、类与类之间都是通过new一个对方的实例进行相互调用,这样在开发过程中有一个好处,可以清晰的知道在使用哪个具体的实现。随着软件体积越来越庞大,逻辑越来越复杂,当需要更换实现方式,或者依赖第三方系统的某些接口时,这种相互之间持有具体实现的方式不再合适。为了应对这种情况,就要采用契约式编程:相互之间依赖于规定好的契约(接口),不依赖于具体的实现。这样带来的好处是相互之间的依赖变得非常简单,又称松耦合。至于契约和具体实现的映射关系,则会通过配置的方式在程序启动时由运行时确定下来。这就会用到DI。
依赖注入(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中依赖注入AutoMapper的方法示例详解ASP.NET Core 在 JSON 文件中配置依赖注入详解ASP.NET Core 中的框架级依赖注入解读ASP.NET 5 & MVC6系列教程(7):依赖注入ASP.NET MVC实现依赖注入的完整过程ASP.NET Core 过滤器中使用依赖注入知识点总结.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)详解asp.net core 依赖注入.NET学习笔记之默认依赖注入

core
控制台
依赖注入

相关文章
asp.net中TextBox只能输入数字的最简洁的两种方法这篇文章介绍了asp.net中TextBox只能输入数字的最简洁的两种方法,有需要的朋友可以参考一下 2013-11-11
asp.net MVC下使用rest的方法本篇文章主要介绍了asp.net MVC下使用rest的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
2017-09-09
ASP.NET MVC4之js css文件合并功能(3)这篇文章主要介绍了ASP.NET MVC4之js css文件合并功能,使用BundleConfig可以将多个文件请求和并成一个请求,去除文件中的一些注释,空白,起到优化网站的作用,需要的朋友可以参考下 2015-08-08
用类的继承关系(重写父类的方法)实现简易后台代码模板Asp.net的优势就在于快速构建应用,而对于一些最基础数据的增删改以及分页事件或者样式的设定可以通过在父类中写上虚方法来供子类调用,接下来将为您测试一下用子类重写父类的方法实现在模板的基础上衍生变化 2013-01-01
.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)这篇文章主要介绍了.NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 2020-06-06
ASP.NET 在线文件管理最近做了一个 在线文件管理程序,支持浏览服务器所有文件(不单单是站点的文件)。 2009-11-11
分享AjaxPro或者Ajax实现机制今天与大家分享AjaxPro或者Ajax实现机制,需要的朋友可以参考下。 2011-12-12
DataGrid 动态添加模板列 实现代码模版控件能让用户几乎不用花费任何时间就创建出复杂的用户界面. Asp.net有很多控件都使用了模版技术(DataGrid就是一个例子). 而这些控件都工作得很好, 通常, 模版可以被保存为ascx文件以增加复用性. 很有可能, 事前你是不知道你的控件是怎么布局的, 而且你需要动态的添加一些模版以应付不同的事件.
2009-04-04
ASP.NET中的C#基础知识本文主要介绍了ASP.NET中的C#基础知识。具有一定的参考价值,下面跟着小编一起来看下吧 2017-01-01
asp.net安全、实用、简单的大容量存储过程分页 昨晚研究到2点多,对网络上主流的分页存储过程大体看了一遍,但对安全以及如何使用很多文章都没有过多的提及,而我要在这些文章的基础上总结出一个比较实用的分页存储过程,方便大家在以后的项目中使用。
2009-04-04

最新评论

声明:本站(华域联盟www.cnhackhy.com)所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。