ASP.NET Core 6框架揭秘实例演示[22]:如何承载你的后台服务[补充]
借助 .NET提供的服务承载(Hosting)系统,我们可以将一个或者多个长时间运行的后台服务寄宿或者承载我们创建的应用中。任何需要在后台长时间运行的操作都可以定义成标准化的服务并利用该系统来承载,ASP.NET Core应用最终也体现为这样一个承载服务。(本篇提供的实例已经汇总到《ASP.NET Core 6框架揭秘-实例演示版》)
[S1407]利用IHostApplicationLifetime对象关闭应用(源代码)
[S1408]与第三方依赖注入框架的整合(源代码)
[S1409]利用配置初始化承载环境(源代码)
[S1407]利用IHostApplicationLifetime对象关闭应用
我们接下来通过一个简单的实例演示如何利用IHostApplicationLifetime服务来关闭整个承载应用。我们在一个控制台应用程序中定义了如下这个承载服务类型FakeHostedService,并在其构造函数中注入了IHostApplicationLifetime服务。在得到其三个属性返回的CancellationToken对象之后,我们在它们上面分别注册了一个回调在控制台输出相应的文字。
public sealed class FakeHostedService : IHostedService
{
private readonly IHostApplicationLifetime _lifetime;
private IDisposable? _tokenSource; public FakeHostedService(IHostApplicationLifetime lifetime)
{
_lifetime = lifetime;
_lifetime.ApplicationStarted.Register(() => Console.WriteLine("[{0}]Application started", DateTimeOffset.Now));
_lifetime.ApplicationStopping.Register(() => Console.WriteLine("[{0}]Application is stopping.", DateTimeOffset.Now));
_lifetime.ApplicationStopped.Register(() => Console.WriteLine("[{0}]Application stopped.", DateTimeOffset.Now));
} public Task StartAsync(CancellationToken cancellationToken)
{
_tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token.Register(_lifetime.StopApplication);
return Task.CompletedTask;
} public Task StopAsync(CancellationToken cancellationToken)
{
_tokenSource?.Dispose();
return Task.CompletedTask;
}
}
在实现的StartAsync方法中,我们采用如上的方式在等待5秒之后调用IHostApplicationLifetime对象的StopApplication方法关闭应用程序。FakeHostedService服务最后采用如下所示的方式承载于当前应用程序中。
using App;
Host.CreateDefaultBuilder(args)
.ConfigureServices(svcs => svcs.AddHostedService<FakeHostedService>())
.Build()
.Run();
该程序运行之后在控制台上输出的结果如图1所示,从三条消息输出的时间间隔可以确定当前应用程序正是承载FakeHostedService通过调用IHostApplicationLifetime服务的StopApplication方法关闭的。
图1 调用IHostApplicationLifetime服务关闭应用程序
[S1408]与第三方依赖注入框架的整合
《一个Mini版的依赖注入框架》中创建了一个名为Cat的简易版依赖注入框架,并在《与第三方依赖注入框架Cat的整合》中为其创建了一个IServiceProviderFactory<TContainerBuilder>实现类型,具体类型为CatServiceProvider,我们接下来演示一下如何通过注册CatServiceProvider实现与Cat这个第三方依赖注入框架的整合。在创建的演示程序中,我们采用这样的方式定义了三个服务(Foo、Bar和Baz)和对应的接口(IFoo、IBar和IBaz),并在服务类型上标注MapToAttribute特性来定义服务注册信息。
public interface IFoo { }
public interface IBar { }
public interface IBaz { } [MapTo(typeof(IFoo), Lifetime.Root)]
public class Foo : IFoo { } [MapTo(typeof(IBar), Lifetime.Root)]
public class Bar : IBar { } [MapTo(typeof(IBaz), Lifetime.Root)]
public class Baz : IBaz { }
如下所示的FakeHostedService类型表示承载的服务。我们在构造函数中注入了IFoo、IBar和IBaz对象,构造函数提供的调试断言用于验证上述三个服务被成功注入。
public sealed class FakeHostedService: IHostedService
{
public FakeHostedService(IFoo foo, IBar bar, IBaz baz)
{
Debug.Assert(foo != null);
Debug.Assert(bar != null);
Debug.Assert(baz != null);
}
public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
我们在如下的演示程序中创建了一个IHostBuilder对象,通过调用其ConfigureServices方法注册了需要承载的FakeHostedService服务后,我们调用它的UseServiceProviderFactory方法完成了对CatServiceProvider的注册。我们随后调用了CatBuilder的Register方法完成了针对入口程序集的批量服务注册。调用IHostBuilder的Build方法构建出作为宿主的IHost对象并启动它之后,承载的FakeHostedService服务将自动被创建并启动(S1408)。
using App;
using System.Reflection; Host.CreateDefaultBuilder()
.ConfigureServices(svcs => svcs.AddHostedService<FakeHostedService>())
.UseServiceProviderFactory(new CatServiceProviderFactory())
.ConfigureContainer<CatBuilder>(
builder => builder.Register(Assembly.GetEntryAssembly()!))
.Build()
.Run();
[S1409]利用配置初始化承载环境
一个HostBuilderContext上下文由承载针对宿主配置的IConfiguration对象和描述当前承载环境的IHostEnvironment对象组成,后者提供的环境名称、应用名称和内容文件根目录路径可以通过前者来指定,具体的配置项名称定义在如下这个静态类型HostDefaults中。
public static class HostDefaults
{
public static readonly string EnvironmentKey = "environment";
public static readonly string ContentRootKey = "contentRoot";
public static readonly string ApplicationKey = "applicationName";
}
下面我们通过一个简单的实例演示如何利用配置的方式来指定上述三个与承载环境相关的属性。我们定义了如下一个名为FakeHostedService的承载服务,并在构造函数中注入IHostEnvironment对象。FakeHostedService派生于抽象类BackgroundService,我们在在ExecuteAsync方法中将与承载环境相关的环境名称、应用名称和内容文件根目录路径输出到控制台上。
public class FakeHostedService : BackgroundService
{
private readonly IHostEnvironment _environment;
public FakeHostedService(IHostEnvironment environment) => _environment = environment;
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
Console.WriteLine("{0,-15}:{1}", nameof(_environment.EnvironmentName), _environment.EnvironmentName);
Console.WriteLine("{0,-15}:{1}", nameof(_environment.ApplicationName),_environment.ApplicationName);
Console.WriteLine("{0,-15}:{1}", nameof(_environment.ContentRootPath),_environment.ContentRootPath);
return Task.CompletedTask;
}
}
FakeHostedService采用如下形式进行承载。如代码片段所示,为了避免输出日志的“干扰”,我们调用IHostBuilder接口的ConfigureLogging扩展方法将注册的ILoggerProvider对象全部清除。如果调用Host静态类型的CreateDefaultBuilder方法时传入当前的命令行参数,创建的IHostBuilder对象会将其作为配置源,所以我们就能以命令行参数的形式来指定承载上下文的三个属性。
using App;
Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging=>logging.ClearProviders())
.ConfigureServices(svcs => svcs.AddHostedService<FakeHostedService>())
.Build()
.Run();
我们采用命令行的方式启动这个演示程序,并利用传入的命令行参数指定环境名称、应用名称和内容文件根目录路径(确保路径确实存在)。图2所示的输出结果表明,应用程序当前的承载环境与基于宿主的配置是一致的。
图2 利用配置来初始化承载环境
ASP.NET Core 6框架揭秘实例演示[22]:如何承载你的后台服务[补充]的更多相关文章
- ASP.NET Core 6框架揭秘实例演示[07]:文件系统
ASP.NET Core应用具有很多读取文件的场景,如读取配置文件.静态Web资源文件(如CSS.JavaScript和图片文件等).MVC应用的视图文件,以及直接编译到程序集中的内嵌资源文件.这些文 ...
- ASP.NET Core 6框架揭秘实例演示[08]:配置的基本编程模式
.NET的配置支持多样化的数据源,我们可以采用内存的变量.环境变量.命令行参数.以及各种格式的配置文件作为配置的数据来源.在对配置系统进行系统介绍之前,我们通过几个简单的实例演示一下如何将具有不同来源 ...
- ASP.NET Core 6框架揭秘实例演示[09]:配置绑定
我们倾向于将IConfiguration对象转换成一个具体的对象,以面向对象的方式来使用配置,我们将这个转换过程称为配置绑定.除了将配置树叶子节点配置节的绑定为某种标量对象外,我们还可以直接将一个配置 ...
- ASP.NET Core 6框架揭秘实例演示[10]:Options基本编程模式
依赖注入使我们可以将依赖的功能定义成服务,最终以一种松耦合的形式注入消费该功能的组件或者服务中.除了可以采用依赖注入的形式消费承载某种功能的服务,还可以采用相同的方式消费承载配置数据的Options对 ...
- ASP.NET Core 6框架揭秘实例演示[11]:诊断跟踪的几种基本编程方式
在整个软件开发维护生命周期内,最难的不是如何将软件系统开发出来,而是在系统上线之后及时解决遇到的问题.一个好的程序员能够在系统出现问题之后马上定位错误的根源并找到正确的解决方案,一个更好的程序员能够根 ...
- ASP.NET Core 6框架揭秘实例演示[12]:诊断跟踪的进阶用法
一个好的程序员能够在系统出现问题之后马上定位错误的根源并找到正确的解决方案,一个更好的程序员能够根据当前的运行状态预知未来可能发生的问题,并将问题扼杀在摇篮中.诊断跟踪能够帮助我们有效地纠错和排错&l ...
- ASP.NET Core 6框架揭秘实例演示[13]:日志的基本编程模式[上篇]
<诊断跟踪的几种基本编程方式>介绍了四种常用的诊断日志框架.其实除了微软提供的这些日志框架,还有很多第三方日志框架可供我们选择,比如Log4Net.NLog和Serilog 等.虽然这些框 ...
- ASP.NET Core 6框架揭秘实例演示[14]:日志的进阶用法
为了对各种日志框架进行整合,微软创建了一个用来提供统一的日志编程模式的日志框架.<日志的基本编程模式>以实例演示的方式介绍了日志的基本编程模式,现在我们来补充几种"进阶" ...
- ASP.NET Core 6框架揭秘实例演示[15]:针对控制台的日志输出
针对控制台的ILogger实现类型为ConsoleLogger,对应的ILoggerProvider实现类型为ConsoleLoggerProvider,这两个类型都定义在 NuGet包"M ...
随机推荐
- nginx入门教程 (转)
1.Nginx 状态码配置和错误文件 server { # 配置访问 /test.js 时报 403 错 location /test.js { return 403; } # 配置访问 /404 时 ...
- Android 如何让EditText不自动获取焦点&隐藏软键盘
感谢大佬:https://blog.csdn.net/a18615971648/article/details/72869345 有时候的项目当中进入某个页面edittext会自动获取焦点弹出软键盘, ...
- 关于SVN常用命令之export
SVN官方命令参考地址:http://www.subversion.org.cn/svnbook/nightly/svn.ref.html 关于export命令 导出一个干净的不带.svn文件夹的目录 ...
- Linux-一次执行多个命令 ; && ||
一次执行多个命令,多个命令之间用:号隔开 cmd1;cmd2:cmd3 这样前后执行的时候没有依赖性,如果有下列要求呢 1. cmd1执行失败那就不要执行后面的命令 2. cmd1失败了才去指令后面的 ...
- springcloud+gateway微服务整合swagger
单一的微服务集成swagger: maven: <dependency> <groupId>io.springfox</groupId> <artifactI ...
- Ubuntu18配置静态IP地址
1. 记住网卡名称 ifconfig 2. 记住网关地址 netstat -rn 3. 配置静态IP 注意:Ubuntu18固定IP的方式跟Ubuntu18之前版本的的配置方式不同, Ubuntu18 ...
- Java四舍五入保留n位小数的常用写法
1. 使用BigDecimal double v = 1.233; double res = new BigDecimal(v).setScale(2, RoundingMode.HALF_UP).d ...
- suse 12 二进制部署 Kubernetets 1.19.7 - 第04章 - 部署docker服务
文章目录 1.4.部署docker 1.4.0.下载docker二进制文件 1.4.1.配置docker镜像加速 1.4.2.配置docker为systemctl管理 1.4.3.启动docker服务 ...
- c++ 文本处理
c++ 文本处理 1.使用sstream版本 (1)功能:截取第一列为1以后的数据,如下图,截取第5行(包括第5行)以后的数据,前面4行数据丢弃. (2)代码:textProc.cc #include ...
- Anchor-free目标检测综述 -- Keypoint-based篇
早期目标检测研究以anchor-based为主,设定初始anchor,预测anchor的修正值,分为two-stage目标检测与one-stage目标检测,分别以Faster R-CNN和SSD作 ...