Использование Hangfire BackgroundJob.Schedule с httpclientfactory DI - PullRequest
1 голос
/ 17 октября 2019

У меня есть 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);


        }
...