首页 > 解决方案 > Dotnet Core 3.1 控制台应用程序托管可选的 Web API 以进行控制

问题描述

我正在 Dotnet Core 3.1 中编写控制台应用程序。它已经配置为使用依赖注入Microsoft.Extensions.DependencyInjection,方法如下:

public static class Program
{
  public static IServiceProvider ServiceProvider { get; private set; }

  public static int Main(string[] args)
  {
    // ...
    ServiceProvider = ConfigureServices().BuildServiceProvider();
    // ...
  }

  public static IServiceCollection ConfigureServices()
  {
    return new ServiceCollection()
      .AddLogging(cfg =>
      {
        // ...
      }
      // ...
  }
}

我正在尝试设置一个简单的 HTTP API 来提供对应用程序的一些基本控制。我想避免使用 ASP.Net MVC 或任何太重的东西。我只需要能够发出简单的指令并获得基本状态。它将全部是 JSON - 不需要 Razor 或类似的东西。

我还有另外两个(未完成的)课程:

public class ApiRunner
{
  public IWebHost WebHost { get; }

  public ApiRunner()
  {
    WebHost = new WebHostBuilder()
      .UseKestrel()
      .UseUrls("http://*:5000")
      .UseStartup<ApiStartup>()
      .Build();
  }

  public void Start()
  {
    Task.Run(() => WebHost.Run());
  }

  public void Stop()
  {
    WebHost.StopAsync();
  }
}

public class ApiStartup
{
  public void Configure(IApplicationBuilder app)
  {
    app.UseRouter(r =>
    {
      r.MapGet("/", async (request, response, routeData) =>
      {
        response.Headers["content-type"] = "text/plan";
        response.WriteAsync("Hello World!");
      });
    }
  }
}

ApiStartup除非我添加到我的班级,否则上述内容不起作用:

public void ConfigureServices(IServiceCollection services)
{
  services.AddRouting();
}

但这似乎有两个 DI 堆栈在彼此之上运行:一个用于主程序,一个用于 API。我确实尝试在 中添加services.AddRouting();到主 DI 配置Program.cs,但是 (1) 这不起作用 - 我得到了与根本没有它时相同的异常,这让我相信 API 想要使用它的自己的 DI,以及 (2) 我不一定想用我认为是一个有点独立的模块的特定于 API 的服务来污染我的主要 DI。

我只需要一个在我的控制台应用程序中运行的轻量级 HTTP 服务器,它允许我发出简单的命令并获取状态。我可以请一些指示如何实现这一目标吗?谢谢你。

标签: c#apiasp.net-core.net-corekestrel-http-server

解决方案


首先,每个 ASP.NET Core 应用程序都是控制台应用程序,并且只会成为注册了 DI 和相关服务的 Web 应用程序。

其次,您没有遵循服务注册的标准模式;无需自己实例化服务集合,WebHostBuilder 已经先完成了。仅在 ApiStartup 类中注册服务。所以是的,你在两个地方注册。请参阅示例,其中包含日志配置演示的额外好处:

https://github.com/akovac35/Logging.Samples/tree/master/WebApp


推荐阅读