ASP.NET 核心 6 - 我如何获得所需的服务
ASP.NET Core 6 - How do I get required service
我正在按照 MSDN 上排队服务的示例进行操作,但我不知道如何为 MonitorLoop
获取实例,因为 host.Services.GetRequiredService
未定义。如何在 ASP.NET Core 6 中检索它?
或者更好的做法是为 MonitorLoop
使用后台范围的服务? https://docs.microsoft.com/en-us/dotnet/core/extensions/scoped-service
public static class QueueServiceExtensions
{
public static void AddQueueService(this IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<MonitorLoop>();
services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue>(_ =>
{
if (!int.TryParse(configuration["QueueCapacity"], out var queueCapacity))
{
queueCapacity = 100;
}
return new DefaultBackgroundTaskQueue(queueCapacity);
});
// TODO: host.Services is undefined
MonitorLoop monitorLoop = host.Services.GetRequiredService<MonitorLoop>()!;
monitorLoop.StartMonitorLoop();
}
}
这就是我的 Program.cs 的样子
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using QSGEngine.Web.QueueService;
using QSGEngine.Web.SignalR;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// Logging
builder.Host.UseSerilog((context, configuration) =>
{
configuration
.ReadFrom.Configuration(context.Configuration)
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithProperty("Environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))
.WriteTo.Console(
#if DEBUG
restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Verbose,
#else
restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information,
#endif
outputTemplate: builder.Configuration["Serilog:OutputTemplateConsole"]
)
.WriteTo.File(
path: builder.Configuration["Serilog:LogFileLocation"], retainedFileCountLimit: 7, rollingInterval: RollingInterval.Day, buffered: false,
outputTemplate: builder.Configuration["Serilog:OutputTemplateFile"]
);
});
// CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", configurePolicy => configurePolicy
.WithOrigins(builder.Configuration["Configuration:FrontEndUrl"])
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
// Authentication & Authorization
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
// Services
//builder.Services.AddHostedService<PortfolioService>();
builder.Services.AddQueueService(builder.Configuration);
builder.Services.AddControllers();
// Swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// SignalR
//builder.Services.AddSignalR();
builder.Services.AddPortfolioSignalRService();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
// Swagger
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
// CORS
app.UseCors("CorsPolicy");
// Web Sockets
var webSocketOptions = new WebSocketOptions()
{
KeepAliveInterval = TimeSpan.FromSeconds(120)
};
app.UseWebSockets(webSocketOptions);
// Authentication & Authorization
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
// SignalR
//app.MapHub<PortfolioHub>("/portfolios");
app.MapPortfolioSignalR();
app.Run();
我有类似的情况,这是我的具体工作实施:
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// I Create a new Service Colleciton
var services = new ServiceCollection();
// I Configure my services
services.ConfigureServices();
// I build a new service provider from the services collection
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
// Review the FormMain Singleton.
var formMain = serviceProvider.GetRequiredService<FormMain>();
Application.Run(formMain);
}
}
private static void ConfigureServices(this IServiceCollection services)
{
services.AddSingleton<FormMain>();
...
services.AddSingleton<MonitorService>();
}
这也适用于基于网络的应用程序。以下是使用相同模式的 Blazor 应用程序示例:
Program.cs
public static void Main(string[] args)
{
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
logger.Debug($"Application Started {DateTime.Now}");
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog();
}).UseWindowsService();
执行以下来自 Web 应用程序但使用相同概念的操作:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddScopred<ILoginService, LoginService>();
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
var loginService = serviceProvider.GetRequiredService<LoginService>();
var task = loginService.LoginAsync("Test", "Test");
var result = task.GetAwaiter().GetResult();
}
...
}
我正在按照 MSDN 上排队服务的示例进行操作,但我不知道如何为 MonitorLoop
获取实例,因为 host.Services.GetRequiredService
未定义。如何在 ASP.NET Core 6 中检索它?
或者更好的做法是为 MonitorLoop
使用后台范围的服务? https://docs.microsoft.com/en-us/dotnet/core/extensions/scoped-service
public static class QueueServiceExtensions
{
public static void AddQueueService(this IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<MonitorLoop>();
services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue>(_ =>
{
if (!int.TryParse(configuration["QueueCapacity"], out var queueCapacity))
{
queueCapacity = 100;
}
return new DefaultBackgroundTaskQueue(queueCapacity);
});
// TODO: host.Services is undefined
MonitorLoop monitorLoop = host.Services.GetRequiredService<MonitorLoop>()!;
monitorLoop.StartMonitorLoop();
}
}
这就是我的 Program.cs 的样子
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Identity.Web;
using QSGEngine.Web.QueueService;
using QSGEngine.Web.SignalR;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// Logging
builder.Host.UseSerilog((context, configuration) =>
{
configuration
.ReadFrom.Configuration(context.Configuration)
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.WithProperty("Environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))
.WriteTo.Console(
#if DEBUG
restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Verbose,
#else
restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information,
#endif
outputTemplate: builder.Configuration["Serilog:OutputTemplateConsole"]
)
.WriteTo.File(
path: builder.Configuration["Serilog:LogFileLocation"], retainedFileCountLimit: 7, rollingInterval: RollingInterval.Day, buffered: false,
outputTemplate: builder.Configuration["Serilog:OutputTemplateFile"]
);
});
// CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("CorsPolicy", configurePolicy => configurePolicy
.WithOrigins(builder.Configuration["Configuration:FrontEndUrl"])
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
// Authentication & Authorization
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
// Services
//builder.Services.AddHostedService<PortfolioService>();
builder.Services.AddQueueService(builder.Configuration);
builder.Services.AddControllers();
// Swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// SignalR
//builder.Services.AddSignalR();
builder.Services.AddPortfolioSignalRService();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
// Swagger
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
// CORS
app.UseCors("CorsPolicy");
// Web Sockets
var webSocketOptions = new WebSocketOptions()
{
KeepAliveInterval = TimeSpan.FromSeconds(120)
};
app.UseWebSockets(webSocketOptions);
// Authentication & Authorization
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
// SignalR
//app.MapHub<PortfolioHub>("/portfolios");
app.MapPortfolioSignalR();
app.Run();
我有类似的情况,这是我的具体工作实施:
private static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// I Create a new Service Colleciton
var services = new ServiceCollection();
// I Configure my services
services.ConfigureServices();
// I build a new service provider from the services collection
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
// Review the FormMain Singleton.
var formMain = serviceProvider.GetRequiredService<FormMain>();
Application.Run(formMain);
}
}
private static void ConfigureServices(this IServiceCollection services)
{
services.AddSingleton<FormMain>();
...
services.AddSingleton<MonitorService>();
}
这也适用于基于网络的应用程序。以下是使用相同模式的 Blazor 应用程序示例:
Program.cs
public static void Main(string[] args)
{
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
logger.Debug($"Application Started {DateTime.Now}");
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog();
}).UseWindowsService();
执行以下来自 Web 应用程序但使用相同概念的操作:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddScopred<ILoginService, LoginService>();
using (ServiceProvider serviceProvider = services.BuildServiceProvider())
{
var loginService = serviceProvider.GetRequiredService<LoginService>();
var task = loginService.LoginAsync("Test", "Test");
var result = task.GetAwaiter().GetResult();
}
...
}