[英]How to run .NET Core Console app using generic host builder
I am trying to figure out how to use hostbuilder pattern to run a console app (not a windows service).我试图弄清楚如何使用主机构建器模式来运行控制台应用程序(而不是 Windows 服务)。 Intent is to keep the flow as similar to a WebApi to keep development practices similar.目的是保持流程与 WebApi 相似,以保持开发实践相似。 I have seen samples for using HostedService or BackGroundService, where they want to run it as a windows service.我已经看到使用 HostedService 或 BackGroundService 的示例,他们希望将其作为 Windows 服务运行。 But If I am looking to run a simple console app, where do I specify my entrypoint class and method?但是如果我想运行一个简单的控制台应用程序,我在哪里指定我的入口点类和方法? From hostbuilder.Build(), I can see Run() and RunAsync() methods.从 hostbuilder.Build() 中,我可以看到 Run() 和 RunAsync() 方法。 But I am unable to figure out what will it execute?但我无法弄清楚它将执行什么?
I have seen other examples of where you can create servicecollection and then use serviceprovider.GetService().SomeMethod() to start the process.我已经看到了可以创建 servicecollection 然后使用 serviceprovider.GetService().SomeMethod() 启动该过程的其他示例。 But that kind of deviates from what we want to do.但这偏离了我们想要做的事情。 So please suggest how to specify startup process.所以请建议如何指定启动过程。 We are using 3.1 .Net Core.我们使用的是 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()
;
}
EDIT: .NET 6 update is below ↓编辑: .NET 6 更新如下↓
I'd start off with the default worker
template.我将从默认的worker
模板开始。 It comes with necessary packages pre-installed.它预装了必要的软件包。 If you already have a project, install Microsoft.Extensions.Hosting
package.如果您已经有一个项目,请安装Microsoft.Extensions.Hosting
包。
dotnet new worker -n MyCli
Then open up the Program.cs
and build the host.然后打开Program.cs
并构建主机。 Remove the Worker
hosted service if you don't want to go with the hosted service route.如果您不想使用托管服务路线,请删除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.
});
}
Build your logic:建立你的逻辑:
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");
}
}
Then register the class inside .ConfigureServices method然后在 .ConfigureServices 方法中注册类
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddTransient<MyService>();
});
Now you can resolve and call it inside the Main
method:现在您可以在Main
方法中解析并调用它:
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
var myService = host.Services.GetRequiredService<MyService>();
myService.DoSomething();
}
With .NET 6, boilerplate is reduced significantly.使用 .NET 6,样板文件显着减少。 We can rewrite our Program.cs
as:我们可以将我们的Program.cs
重写为:
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");
}
}
Basically:基本上:
Instantiate your host builder and configure your services and whatnot.实例化您的主机构建器并配置您的服务等等。
Make a class with a method for your programme and register that class as a service.为您的程序创建一个带有方法的类并将该类注册为服务。
Build the host, create a scope, get an instance of your class, call your method.构建主机,创建范围,获取您的类的实例,调用您的方法。
My programme is the mehod MainAsync
in my class ProgramAsync
.我的程序是我的类ProgramAsync
中的MainAsync
。
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.");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.