C# ConsoleApp 注入启动?
C# ConsoleApp injection startup?
我有一个简单的 C# .NET Core 5 控制台应用程序,我需要向其添加依赖项注入 (Microsoft.Extensions.DependencyInjection)。如果它想启动微服务,我知道该怎么做,但是如果我只想 运行 它作为带有 DI 的常规控制台应用程序怎么办?
我得到了这个代码:
static void Main(string[] args)
{
var serviceName =
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
var configurationBuilder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json").Build();
var appSettings = configurationBuilder.Get<AppSettings>();
Log.Information("{@serviceName} test starting up.", serviceName);
Host.CreateDefaultBuilder(args)
.UseMyAppMQ(context => context.UseSettings(appSettings.MQSettings))
.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration))
.ConfigureServices((hostContext, services) =>
{
services
.Configure<MQSettings>(configurationBuilder.GetSection("MQSettings"))
.AddTransient<ITestController>(s => new TestController());
})
.Build().Run();
Log.Information("{@serviceName} test closing down.", serviceName);
}
我需要一个可以 运行 我的底层 class 运行 方法的入口点,但是如何?
此致
您需要实现IHostedService
接口(或扩展BackgroundService
基础class)并使用services.AddHostedService<YourServiceClass>()
注册它或
builder.Services.AddHostedService<YourServiceClass>()
,如果使用 .NET 6 minimal API,如 in official docs 所述。在这种情况下,IHostedService.StartAsync
将是您的切入点。
但是,如果您只需要一个带有 DI 的简单控制台应用程序,它看起来确实效率很低。正如@Panagiotis Kanavos 建议的那样,您可以在没有 运行 的情况下构建主机,因为这样您就可以将它用作 DI 容器的包装器并解析任何已注册的服务。在这种情况下,代码的入口点是构建主机后的下一行,您可以在其中使用
解析任何已注册的依赖项
var host = Host.CreateDefaultBuilder(args)
...
.Build();
host.Services.GetService<YouService>()
但对于控制台应用程序来说,它仍然是一个低效的解决方案,因为你只需要 DI 容器,而不是整个主机。只需使用任何第三方 DI 框架(如 Autofac、Ninject 或任何其他框架)而不是 Microsoft.Extensions.DependencyInjection
。他们的设置通常是 quite minimalistic,您将只获得包含服务的 DI 容器,没有其他任何东西。您仍然可以使用配置包和记录器,只需将它们注册到您的容器中,就像您之前使用 UseXxxx 方法所做的那样。
我有一个简单的 C# .NET Core 5 控制台应用程序,我需要向其添加依赖项注入 (Microsoft.Extensions.DependencyInjection)。如果它想启动微服务,我知道该怎么做,但是如果我只想 运行 它作为带有 DI 的常规控制台应用程序怎么办?
我得到了这个代码:
static void Main(string[] args)
{
var serviceName =
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
var configurationBuilder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json").Build();
var appSettings = configurationBuilder.Get<AppSettings>();
Log.Information("{@serviceName} test starting up.", serviceName);
Host.CreateDefaultBuilder(args)
.UseMyAppMQ(context => context.UseSettings(appSettings.MQSettings))
.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration))
.ConfigureServices((hostContext, services) =>
{
services
.Configure<MQSettings>(configurationBuilder.GetSection("MQSettings"))
.AddTransient<ITestController>(s => new TestController());
})
.Build().Run();
Log.Information("{@serviceName} test closing down.", serviceName);
}
我需要一个可以 运行 我的底层 class 运行 方法的入口点,但是如何?
此致
您需要实现IHostedService
接口(或扩展BackgroundService
基础class)并使用services.AddHostedService<YourServiceClass>()
注册它或
builder.Services.AddHostedService<YourServiceClass>()
,如果使用 .NET 6 minimal API,如 in official docs 所述。在这种情况下,IHostedService.StartAsync
将是您的切入点。
但是,如果您只需要一个带有 DI 的简单控制台应用程序,它看起来确实效率很低。正如@Panagiotis Kanavos 建议的那样,您可以在没有 运行 的情况下构建主机,因为这样您就可以将它用作 DI 容器的包装器并解析任何已注册的服务。在这种情况下,代码的入口点是构建主机后的下一行,您可以在其中使用
解析任何已注册的依赖项var host = Host.CreateDefaultBuilder(args)
...
.Build();
host.Services.GetService<YouService>()
但对于控制台应用程序来说,它仍然是一个低效的解决方案,因为你只需要 DI 容器,而不是整个主机。只需使用任何第三方 DI 框架(如 Autofac、Ninject 或任何其他框架)而不是 Microsoft.Extensions.DependencyInjection
。他们的设置通常是 quite minimalistic,您将只获得包含服务的 DI 容器,没有其他任何东西。您仍然可以使用配置包和记录器,只需将它们注册到您的容器中,就像您之前使用 UseXxxx 方法所做的那样。