在.NET Core微服务中使用HostBuilder和Generic Host【转载】
基于控制台的服务中探索一个简单模式,以解决跨领域问题。
“通用” Host和HostBuilder是随.NET Core 2.1发布而发布的新功能组件的组件。它们的一个用例是通过提供用于添加横切关注点(例如依赖注入,配置和日志记录)的模式来简化基于控制台的服务的创建。
介绍
自ASP.NET Core 1.0发布以来,我们有了WebHostBuilder类,它允许我们配置和构建WebHost。然后,当服务器(Kestrel)接受并处理HTTP请求时,它将处理应用程序的生命周期。在ASP.NET Core 2.0中,WebHostBuilder得到了一些进一步的改进和简化。WebHostBuilder允许我们执行诸如使用依赖注入容器来配置服务的事情; 通常是由Microsoft提供的作为ASP.NET Core一部分的容器。WebHostBuilder还允许我们将来自多个源的配置加载到键/值对的最终配置表示中。
对于ASP.NET Core Web应用程序来说,这些工作非常好,但是到目前为止,在其他类型的应用程序的框架中没有类似的选项!
注意:请记住,这篇文章是基于ASP.NET Core 2.1预览版1发布的。因此,在公开预览期间以及在最终发布2.1之前,事情可能会根据预览期间收到的反馈进行更改。
介绍IHost和HostBuilder
使用.NET Core 2.1的开发人员可以使用的新选项是新的“通用”主机,它使开发人员能够轻松设置横切关注点,例如针对非Web焦点应用程序的日志记录,配置和依赖注入。团队已经认识到,将主机绑定到HTTP的关注可能不是一个理想的解决方案,因为其中许多这些东西是其他应用程序类型的通用要求。
可以使用这个地方的一个例子是在需要运行后台处理任务的控制台应用程序中,例如可能处理队列中的消息。现在,这些类型的服务在基于云的本地基于容器的体系结构中很常见。
在.NET Core的当前2.0版本中,当然可以在控制台应用程序中使用日志记录,配置和DI库。在工作中,我们有许多微服务,它们处理来自队列的消息和数据丰富任务。我们必须自己手动包含和设置这些常见问题。虽然这是可能的,但在应用程序中设置DI设置之类的东西需要一些管道。
建立一个主机
要创建主机,我们可以使用新的HostBuilder,它具有与现有WebHostBuilder类似的一组方法和扩展。因此,使用ASP.NET Core的任何人都应该熟悉这些模式。
有一个主要的区别需要注意。HostBuilder不提供扩展方法,允许您像使用WebHostBuilder一样使用启动类。这个决定主要是为了避免在幕后创建两个独立的DI容器。使用通用主机,配置单个服务集合,然后用于构建最终服务提供者。
在您的应用程序的Main方法中,您可以先创建一个HostBuilder,然后使用扩展方法向DI注册服务,读取配置并配置您的应用程序所需的日志记录。
解释该功能的最佳方式是举一个例子。如果你想查看完整的示例代码,你可以从GitHub中获取它。
如果我们看看这个控制台应用程序的Main方法,我们可以探索为我们的应用程序创建一个Host。
如果您已经使用过ASP.NET Core,并且已经看到了WebHost构建器,特别是在1.0时间框架中,这看起来可能非常熟悉。我们首先创建一个HostBuilder,然后我们可以使用它来定义我们想要创建的主机。本例中的第一个方法是ConfigureAppConfiguration方法。这个方法允许我们配置应该使用哪个配置提供者来为我们的应用程序构造配置值的最终表示。
这与使用WebHostBuilder时可以自定义配置的方式相同。在这个例子中,我们已经说过,我们希望首先从appsettings.json文件中读取配置值,然后是环境变量,最后是传递到应用程序中的任何参数。
接下来我们调用ConfigureServices,就像WebHostBuilder一样,允许我们用ServiceCollection注册服务。使用ServiceCollection上的扩展方法执行注册,一旦完成,将使我们能够在我们的应用程序中有DI可用的任何地方获取这些注册的实例。
在这种情况下,第一个添加了ASP.NET Core Options服务,第二个为IOptions绑定设置了注册。最后的服务注册是我稍后会谈到的。
最后一节,ConfigureLogging如你所期望的那样设置应用程序的日志记录。在这种情况下,我们添加控制台日志记录,它使用应用程序配置中的值来确定要记录的内容。
本示例中的日志记录配置与使用模板创建的默认ASP.NET Core Web应用程序中的配置相同。
最后一步是在构建和启动应用程序的HostBuilder上调用RunConsoleAsync。它会一直运行,直到CTRL + C被用来触发它关闭。
完成任务
如果我们把它留在这里,服务就不会太好。此时我们只是运行一个控制台应用程序,但实际上并没有做任何有用的事情。因此我们需要一种方法来定义应用程序应该执行的工作。
为这种服务风格推荐的模式是利用新的IHostedService功能,首先在ASP.NET Core 2.0中引入。
这里我们有一个基本的IHostedService实现,它将在这个服务中运行...
我不会深入研究这些代码,但我会总结一下它在做什么。当应用程序启动时,它将在此服务上调用StartAsync。在该方法中,我们创建了一个每5秒钟执行一次工作的定时器。
作品本身在DoWork中定义。这里只是用户将ILogger记录为信息。这包括从应用程序配置中检索的消息。这是通过DI传递给服务的IOptions对象访问的。
在关机时,StopAsync被调用,服务在应用程序被终止之前清理一点。这是一个非常人为的例子,但我想简单地把事情放在一起,并专注于这些部分如何组合在一起。
通过定义IHostedService实现,我们只需使用ConfigureServices中的以下常见操作(我们在前面看到)将其注册到DI容器。
services.AddSingleton<IHostedService, PrintTextToConsoleService>();
如果我们需要在此服务中运行各种东西,我们可以添加多个托管服务。
概要
使用这种新的“通用”主机概念有很多情况。在这篇文章中,我们已经探索了一个非常基本的例子,但是我不需要太多的工作来简化我们环境中的一些微服务。对于Web应用程序和服务有一个通用模式,并且可以轻松访问DI,日志记录和配置等特性,这是非常受欢迎的。