C#控制台应用程序注入启动?

4

我有一个简单的 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);
}

我需要一个入口点来运行我的底层类的运行方法,但怎么做呢?

敬礼


1
这已经在工作模板中提供,实际上需要的代码要少得多。运行 dotnet new worker 并检查代码。这将创建一个控制台应用程序,启动所有已注册的 BackgroundService 派生类。如果您想在其中一个服务结束时终止应用程序,则必须通过注入 IHostApplicationLifetime 并调用 StopApplication() 来告诉主机。 - Panagiotis Kanavos
将您的类与其接口注入(例如:.AddTransient<IMyClass,MyClass>)然后使用中间件调用您的类运行方法(例如:app.Use())。请参见此链接:https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection-usage 和 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-6.0。 - GH DevOps
否则,不要调用 Run(),只需使用 Build() 获取主机。从主机显式请求“服务”,调用其方法,并在完成后退出应用程序。 - Panagiotis Kanavos
1个回答

4
你需要实现 IHostedService 接口(或扩展 BackgroundService 基类),并使用 services.AddHostedService<YourServiceClass>()builder.Services.AddHostedService<YourServiceClass>() 进行注册,如果使用 .NET 6 minimal API,如 官方文档 所述。在这种情况下,IHostedService.StartAsync 将是您的入口点。
然而,如果您只需要一个带有 DI 的简单控制台应用程序,似乎非常低效。正如 @Panagiotis Kanavos 建议的那样,您可以构建主机而不运行它,因为这样您就可以将其用作 DI 容器周围的包装器,并解析任何已注册的服务。在这种情况下,您的代码的入口点是构建主机后的下一行,您可以在其中解析任何已注册的依赖项。
var host = Host.CreateDefaultBuilder(args)
   ...
   .Build();
host.Services.GetService<YouService>()

但是对于仅限控制台应用程序来说,它仍然是一种低效的解决方案,因为您只需要 DI 容器,而不是整个主机。 直接使用任何第三方 DI 框架(如 Autofac、Ninject 或其他)来替代 Microsoft.Extensions.DependencyInjection 即可。 它们的设置通常 非常简约,您只会得到带有服务的 DI 容器,没有其他任何东西。 您仍然可以使用配置包和记录器,只需将它们与之前使用 UseXxxx 方法相同地注册到容器中即可。


谢谢,我在这种情况下选择了Autofac。 - Banshee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接