我开发了一个 .NET Core Web 应用程序。
该 Web 应用程序应定期从同一 Web 应用程序的某个控制器获取信息。为了实现它,我创建了一个实现 IHostedService 接口的类。然后,在 Program.cs 文件中,我添加了该服务:
services.AddHostedService<EventPollingService>()
通过这样做,我意识到托管服务被实例化为单例对象。
另一方面,我在托管服务构造函数中传递
IHttpContextAccessor accessor
以使用 DI 使其可用。
问题是,为了在同一个应用程序中调用控制器,我需要传递绝对 URL,因此在托管服务构造函数中我这样做:
_baseUrl = accessor.HttpContext?.Request.BaseUrl() ?? string.Empty;
问题在于,在这种情况下 HttpContext 为 null。
另一方面,在托管服务内部,我需要对数据库进行一些插入,因此我认为在获取 DbContext 实例时会遇到类似的问题,因为它是作为作用域服务添加的。
我该怎么做?如果这种方法在技术上不可行,您能否推荐另一种方法?
托管服务没有
HttpContext
,因为它们不直接接收 HTTP 请求。如果您想获取正在运行托管服务的 URL,请使用托管服务中的 ApplicationStarted
触发器来访问服务器功能。下面的代码解释了我的意思:
public class EventPollingService : IHostedService
{
private readonly IServer _server;
private readonly IHostApplicationLifetime _hostApplicationLifetime;
private ICollection<string> _urls;
public EventPollingService(IServer server, IHostApplicationLifetime hostApplicationLifetime)
{
_server = server;
_hostApplicationLifetime = hostApplicationLifetime;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_hostApplicationLifetime.ApplicationStarted.Register(() =>
{
_urls = _server.Features.Get<IServerAddressesFeature>()?.Addresses ?? null;
});
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}