在 .Net Core Worker Service 中托管 Web API - 无法引用 IWebHostEnvironment

Tor*_*reS 5 .net-core asp.net-core

我正在创建一个 .NET Core Worker Service,并希望为该服务公开 ASP.Net Core Web API。我正在使用 .NET Core 3.0。最初,我的计划是用 IWebHostBuilder 替换 IHostBuilder 并添加一个 Startup 类,就像常规的 Asp.Net Core Web 应用程序一样(不过,这可能过于简化了)。

我的计划是简单地尝试更换

public static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)                
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddHostedService<Worker>();
                });
        }
Run Code Online (Sandbox Code Playgroud)

public static IWebHostBuilder CreateHostBuilder(string[] args)
        {
            return WebHost.CreateDefaultBuilder(args)
                .ConfigureServices(services =>
                {
                    services.AddHostedService<Worker>();
                }).UseStartup<Startup>();            
        }
Run Code Online (Sandbox Code Playgroud)

这可能根本不起作用,但至少它是一个起点......阻止我尝试这种方法的是我无法实现我的Startup类,因为IWebHostEnvironment它不可用。

这是我的

<PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <UserSecretsId>dotnet-WorkerServices-0E977A2C-F0C8-49E7-B00A-5EB01B99FBEB</UserSecretsId>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
    <PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
    <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.0.0" />
  </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

据我所知,IWebHostEnvironment应该在Microsoft.Extensions.Hosting.Abstractionsnuget 包中,但引用它似乎不起作用。

有没有人有任何想法?-谢谢!

小智 9

我做了很多研究,我使用了一些格式不正确且缺乏性能的新方法来解决这个问题,我试图找到解决这个问题的正确方法,最后,我解决了它,并分享了我在这方面的经验邮政。您可以使用以下 100% 有效的步骤,此外,您还可以从我的 GitHub 个人资料中克隆 Worker-Service Web-API 模板。

实际上,您不需要使用 IWebHostBuilder。以下步骤足以在 .net core 辅助服务中自托管 WebAPI 并在 Windows 服务中托管辅助服务:

  1. 创建一个简单的控制台应用程序。
  2. 在控制台应用程序中使用 NuGet 安装包“Microsoft.AspNetCore.App”和“Microsoft.Extensions.Hosting.WindowsServices”。
  3. 创建一个名为 Worker.cs 的空文件,并将以下代码放入其中:
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace WorkerServiceWebAppTemplate
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;

        public Worker(ILogger<Worker> logger)
        {
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的类是你的worker服务主文件,它继承自BackgroundService,就我个人而言,我大部分时间都继承IHostedService。

  1. 创建另一个名为 Startup.cs 的文件并放入以下代码行:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;

namespace WorkerServiceWebAppTemplate
{
    public class Startup
    {
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
                app.UseDeveloperExceptionPage();
            else
                app.UseHsts();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGet("/", async context =>
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Startup 文件是您的 Web 服务器文件,它启动一个主机并有一个简单的 GET API (/) 返回一条简单的消息,您可以扩展它。

  1. 最后,您必须同时启动工作人员服务和主机。更改您的 Program.cs,如以下代码:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace WorkerServiceWebAppTemplate
{
    class Program
    {
        static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        private static IHostBuilder CreateHostBuilder(string[] args)
        {
            return Host.CreateDefaultBuilder(args)
                .UseWindowsService()
                .ConfigureServices((hostBuilderContext, services) =>
                {
                    services.AddHostedService<Worker>();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Program.cs 文件中的以下几行可以发挥作用:

                .UseWindowsService()
                .ConfigureServices((hostBuilderContext, services) =>
                {
                    services.AddHostedService<Worker>();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
Run Code Online (Sandbox Code Playgroud)


Hen*_*man 7

向 API 项目添加服务要容易得多。这只是额外的一行。

如果您不能或不想重新开始,请手动更改您的项目。算了IWebHostBuilder,它现在已经过时或不推荐使用了。

我可以在这里发布一些片段,但要容易得多:创建一个临时 API 项目,复制 Program 和 Startup 类(但保留您的命名空间),然后在 Startup 中:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHostedService<Worker>();  // the worker will run
    services.AddControllers();
}
Run Code Online (Sandbox Code Playgroud)

  • 是的,这有效,谢谢!然而,向使用_Worker Service_模板创建的项目添加Web api支持并不简单,因为这似乎是一个nuget/包版本问题(或者其他我不明白的问题),这仍然让我感到困扰。我可以阅读的文档的任何建议都可以解释为什么添加包含正确类型和方法的 nuget 包(看似)仍然不允许我使用这些 API? (2认同)