这个答案基于以下标准:
我想在简单的控制台应用程序中使用新的通用主机CreateDefaultBuilder
,但不使用任何ASP.NET Web内容,并且还能够将启动逻辑存储在 startup.cs
中,以配置 AppConfiguration
和 Services。
因此,我花了一整个上午时间来弄清楚如何做到这一点。这是我想出来的方法...
该方法需要的唯一NuGet包是Microsoft.Extensions.Hosting
(在撰写本文时,版本为3.1.7
)。这是一个指向nuget包的链接。该包还必须使用CreateDefaultBuilder()
才能使用,所以您可能已经添加了它。
在将扩展添加到项目后(扩展代码在答案底部),您需要将程序入口设置类似于下面的代码:
using Microsoft.Extensions.Hosting;
class Program
{
static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
您需要添加一个Startup.cs
文件,它应该如下所示:
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
}
}
然后,您可以像在典型的ASP.NET Core应用程序中一样配置您的服务(无需安装ASP.NET Core Web Hosting)。
演示项目
我创建了一个.NET Core 3.1控制台演示项目,执行各种操作,如IHostedService
实现、BackgroundService
实现,瞬态/单例服务。我还注入了IHttpClientFactory
和IMemoryCache
以提高性能。
克隆该仓库并试一试。
工作原理
我创建了一个IHostBuilder
扩展方法,它简单地实现了我们都习惯使用的IHostBuilder UseStartup<TStartup>(this IHostBuilder hostBuilder)
模式。
由于CreateDefaultBuilder()
添加了所有基础内容,因此没有太多需要添加的内容。我们唯一关心的是获取IConfiguration
并通过ConfigureServices(IServiceCollection)
创建我们的服务管道。
扩展方法源代码
public static class HostBuilderExtensions
{
private const string ConfigureServicesMethodName = "ConfigureServices";
public static IHostBuilder UseStartup<TStartup>(
this IHostBuilder hostBuilder) where TStartup : class
{
hostBuilder.ConfigureServices((ctx, serviceCollection) =>
{
var cfgServicesMethod = typeof(TStartup).GetMethod(
ConfigureServicesMethodName, new Type[] { typeof(IServiceCollection) });
var hasConfigCtor = typeof(TStartup).GetConstructor(
new Type[] { typeof(IConfiguration) }) != null;
var startUpObj = hasConfigCtor ?
(TStartup)Activator.CreateInstance(typeof(TStartup), ctx.Configuration) :
(TStartup)Activator.CreateInstance(typeof(TStartup), null);
cfgServicesMethod?.Invoke(startUpObj, new object[] { serviceCollection });
});
return hostBuilder;
}
}