У меня есть API, который использует httpclientfactory для создания различных типизированных httpclients, используя services.addhttpclient <> (). Я начал интегрировать Hangfire с моим сервисом из-за длительных рабочих мест. Все работало нормально, пока я не попытался использовать метод schf Hangfires "BackgroundJob.Schedule". Он запускается, планирует задачу, но когда он пытается выполнить код, который я получаю:
"Unable to resolve service for type 'System.Net.Http.HttpClient' while attempting to activate 'BackupApi.BackupApiService'."
При попытке использовать метод Enqueue это работает без проблем. Kinda потерял atm, все помощь высоко ценится. Я предполагаю, что каким-то образом, когда задание запланировано, зависимости будут потеряны, а затем попытается использовать 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);
}