如何使用通用主机构建器运行.NET Core Console应用程序

问题描述 投票:0回答:2

我试图弄清楚如何使用主机构建器模式来运行控制台应用程序(而不是Windows服务)。目的是保持流程与 WebApi 相似,以保持开发实践相似。我见过使用 HostedService 或 BackGroundService 的示例,他们希望将其作为 Windows 服务运行。但是,如果我想运行一个简单的控制台应用程序,我在哪里指定我的入口点类和方法?从 hostbuilder.Build() 中,我可以看到 Run() 和 RunAsync() 方法。但我无法弄清楚它会执行什么?

我已经看到了其他示例,您可以在其中创建 servicecollection,然后使用 serviceprovider.GetService().SomeMethod() 来启动该过程。但这有点偏离我们想要做的事情。所以请建议如何指定启动过程。我们正在使用 3.1 .Net Core。

class Program
{
    static async void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
        await host.RunAsync();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureServices((hostBuilderContext, serviceCollection) => new Startup(hostBuilderContext.Configuration).ConfigureServices(serviceCollection))
        .UseSerilog()
        ; 

}
c# asp.net-core .net-core console-application
2个回答
91
投票

编辑: .NET 6 的更新如下 ↓
.NET 7 或 .NET 8 没有太大变化。


我将从默认的

worker
模板开始。它预装了必要的软件包。如果您已有项目,请安装
Microsoft.Extensions.Hosting
包。

dotnet new worker -n MyCli

然后打开

Program.cs
并构建主机。如果您不想采用托管服务路线,请删除
Worker
托管服务。

public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                // remove the hosted service
                // services.AddHostedService<Worker>();

                // register your services here.
            });
}

建立你的逻辑:

internal class MyService
{
    // you can also inject other services
    private ILogger<MyService> _logger;

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

    public void DoSomething()
    {
        _logger.LogInformation("Doing something");
    }
}

然后在.ConfigureServices方法中注册类

Host.CreateDefaultBuilder(args)
    .ConfigureServices((hostContext, services) =>
    {
        services.AddTransient<MyService>();
    });

现在您可以在

Main
方法中解析并调用它:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();
    var myService = host.Services.GetRequiredService<MyService>();
    myService.DoSomething();
}

.NET 6+ 更新

使用 .NET 6,样板文件显着减少。我们可以将

Program.cs
重写为:

using Microsoft.Extensions.Hosting; // Requires NuGet package

var host = Host.CreateDefaultBuilder(args)
    .ConfigureServices(services => { services.AddTransient<MyService>(); })
    .Build();

var my = host.Services.GetRequiredService<MyService>();
await my.ExecuteAsync();

class MyService
{
    private readonly ILogger<MyService> _logger;

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

    public async Task ExecuteAsync(CancellationToken stoppingToken = default)
    {
        _logger.LogInformation("Doing something");
    }
}

9
投票

基本上:

  • 实例化您的主机构建器并配置您的服务等等。

  • 为您的程序创建一个带有方法的类,并将该类注册为服务。

  • 构建主机,创建作用域,获取类的实例,调用您的方法。

我的程序是我班级

MainAsync
中的方法
ProgramAsync

    class Program
    {
        static void Main(string[] args)
        {
            using (IHost host = Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration(cfg =>
                {
                    cfg.AddJsonFile("appsettings.json");
                })
                .ConfigureServices((context, services) =>
                {
                    services.AddDbContext<EquitiesDbContext>(options => { options.UseSqlServer(context.Configuration.GetConnectionString("Equities")); });
                    services.AddScoped<ProgramAsync>();
                })
                .ConfigureLogging((context, cfg) =>
                {
                    cfg.ClearProviders();
                    cfg.AddConfiguration(context.Configuration.GetSection("Logging"));
                    cfg.AddConsole();
                })
                .Build()
                )
            {
                using( IServiceScope scope = host.Services.CreateScope() )
                {
                    ProgramAsync p = scope.ServiceProvider.GetRequiredService<ProgramAsync>();
                    p.MainAsync().Wait();
                }
            }
            Console.WriteLine("Done.");
        }
    }

© www.soinside.com 2019 - 2024. All rights reserved.