我有一个 api,它使用 httpclientfactory 使用 services.addhttpclient<>() 创建不同类型的 httpclients。由于长时间运行的工作,我已经开始将 hangfire 与我的服务集成。在我尝试使用 Hangfires 调度方法“BackgroundJob.Schedule”之前,一切正常。它启动,安排任务,但是当它尝试执行我得到的代码时:
"Unable to resolve service for type 'System.Net.Http.HttpClient' while attempting to activate 'BackupApi.BackupApiService'."
尝试使用 Enqueue 方法时,它可以正常工作。有点丢失自动取款机,非常感谢所有帮助。我的猜测是,当任务安排好以后,当hangfire尝试使用时,依赖项会丢失:
using BackupApi;
var backupApiService = Activate<BackupApiService>();
await backupApiService.AdhocBackup("BlurredServername");
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<IBackupApiService, BackupApiService>()
.ConfigurePrimaryHttpMessageHandler(handler =>
new HttpClientHandler
{
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; }
});
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions
{
SchemaName = "BackupApi",
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
UsePageLocksOnDequeue = true,
DisableGlobalLocks = true
}));
services.Configure<ConnectionInfo>(Configuration.GetSection("ConnectionStrings"));
services.AddHttpContextAccessor();
//services.AddTransient<IBackupApiService, BackupApiService>()
var section = Configuration.GetSection("ConnectionStrings");
services.AddHttpClient<DSDClient>()
.ConfigurePrimaryHttpMessageHandler(handler =>
new HttpClientHandler
{
Credentials = new NetworkCredential(
section["Username"],
section["Password"],
"blurredomain"),
ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => { return true; }
});
services.AddHangfireServer();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
//.AddViewComponentsAsServices();
}
BackupApiService.cs
public class BackupApiService : IBackupApiService
{
public HttpClient _netclient { get; }
private static IOptions<ConnectionInfo> _config;
public DSDClient _dsdclient { get; }
private readonly IHttpContextAccessor _httpContextAccessor;
public BackupApiService(IOptions<ConnectionInfo> config, HttpClient netclient, DSDClient dsdclient, IHttpContextAccessor httpContextAccessor)
{
_config = config;
_httpContextAccessor = httpContextAccessor;
_dsdclient = dsdclient;
_netclient = netclient;
_netclient.Timeout = new TimeSpan(0, 2, 30);
_netclient.DefaultRequestHeaders.Clear();
_netclient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", _config.Value.NetworkerConnectionString);
_netclient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public async Task<string> AdhocBackup(string ServerName)
{
....
}
BackupApiV1Controller
public class BackupApiV1Controller : ControllerBase
{
private readonly IBackupApiService _backupApiService;
public BackupApiV1Controller(IBackupApiService backupApiService)
{
_backupApiService = backupApiService;
}
[HttpPost]
[Route("StartDateBackup/")]
public IActionResult StartDateBackup([FromBody] ServerSchedule serverSchedule)
{
var resp = BackgroundJob.Schedule(() => _backupApiService.AdhocBackup(serverSchedule.Servername), serverSchedule.Date);
return Ok();
}
[HttpPost]
[Route("StartAdhocBackup/")]
public IActionResult StartAdhocBackup([FromBody] Server server)
{
var resp = BackgroundJob.Enqueue(() => _backupApiService.AdhocBackup(server.Servername));
return Ok(resp);
}