Ядро ASP.Net Azure Webjob (SDK 3.0.10) D не разрешается - PullRequest
1 голос
/ 02 июля 2019

Я создаю .net ядро ​​веб-задания Azure, запускаемое Q-сообщением в Q-хранилище Azure.

При запуске веб-задания возникает следующая ошибка.

System.InvalidOperationException: «Не удалось разрешить службу для типа« xxx.SERVICE.Cloud.ICloudStorageService »при попытке активировать« xxx.Functions ». '

Есть предложения?

В program.cs / main я подключил DI:

IServiceCollection services = new ServiceCollection();
//...
services.AddTransient<ICloudStorageService, AzureBlobStorageService>();

И «харт» веб-задания

public class Functions
{
    private readonly ICloudStorageService _storageService;

    public Functions(ICloudStorageService cloudStorageService)
    {
        _storageService = cloudStorageService;
    }

    public async Task ProcessQueueMessage(
        [QueueTrigger(AzureQueues.NoShowUploads)] BatchJob job
        , ILogger logger
        )
    {
        //...
    }
}

Класс AzureBlobStorageService реализует интерфейс ICloudStorageService

public class AzureBlobStorageService : ICloudStorageService
{
    //...
}

ОБНОВЛЕНИЕ:

class Program
    {
        static void Main(string[] args)
        {
            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();

            IServiceCollection services = new ServiceCollection();

            services.Configure<SendGridClientOptions>(options =>
            {
                                services.Configure<AzureQueueOptions>(options =>
            {
                configuration.GetSection("AzureQueueOptions").Bind(options);
                options.StorageConnectionString = configuration.GetConnectionString("Storage");
            });
            services.Configure<AzureBlobStorageOptions>(options =>
            {
                configuration.GetSection("AzureBlobStorageOptions").Bind(options);
                options.StorageConnectionString = configuration.GetConnectionString("Storage");
            });

            services.AddTransient<Functions, Functions>();
            services.AddTransient<ICloudStorageService, AzureBlobStorageService>();
            services.AddTransient<WebJobEntryPoint>();

            services.BuildServiceProvider().GetService<WebJobEntryPoint>().Run();

        }
    }

Класс webentrypoint

  public class WebJobEntryPoint
    {
        private readonly MailOptions _mailOptions;
        private readonly SendGridClientOptions _sendGridClientOptions;
        private readonly AzureBlobStorageOptions _azureBlobStorageOptions;
        private readonly AzureQueueOptions _azureQueueOptions;

        public WebJobEntryPoint(
            IOptionsMonitor<SendGridClientOptions> sendGridClientOptionsMonitor,
            IOptionsMonitor<MailOptions> mailOptionsMonitor,
            IOptionsMonitor<AzureBlobStorageOptions> azureBlobStorageOptionsMonitor,
            IOptionsMonitor<AzureQueueOptions> azureQueueOptionsMonitor)
        {
            _sendGridClientOptions = sendGridClientOptionsMonitor.CurrentValue;
            _mailOptions = mailOptionsMonitor.CurrentValue;
            _azureBlobStorageOptions = azureBlobStorageOptionsMonitor.CurrentValue;
            _azureQueueOptions = azureQueueOptionsMonitor.CurrentValue;
        }

        public void Run()
        {
            var builder = new HostBuilder()
                .ConfigureWebJobs(webJobConfiguration =>
                {
                    webJobConfiguration.AddAzureStorageCoreServices();
                    webJobConfiguration.AddAzureStorage(c => c.BatchSize = _azureQueueOptions.BatchSize);
                })
                .ConfigureLogging((context, b) =>
                {
                    b.AddConsole();
                });

            var host = builder.Build();
            using (host)
            {
                host.Run();
            }
        }
    }

1 Ответ

3 голосов
/ 02 июля 2019

При вашем текущем дизайне хост не знает о регистрациях сервисов, которые были сделаны в main.

Вот упрощение текущей настройки на основе того, что было предоставлено в исходном примере:

class Program {
    static void Main(string[] args) {
        var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

        var configuration = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
            .Build();

        var azureQueueOptions = configuration.GetSection("AzureQueueOptions").Get<AzureQueueOptions>();
        azureQueueOptions.StorageConnectionString = configuration.GetConnectionString("Storage");

        var builder = new HostBuilder()
            .ConfigureWebJobs(webJobConfiguration => {
                webJobConfiguration.AddAzureStorageCoreServices();
                webJobConfiguration.AddAzureStorage(c => c.BatchSize = azureQueueOptions.BatchSize);
            })
            .ConfigureServices(services => {
                services.AddTransient<Functions>();
                services.AddTransient<ICloudStorageService, AzureBlobStorageService>();
            })
            .ConfigureLogging((context, config) => {
                config.AddConsole();
            });

        var host = builder.Build();

        host.Run();
    }
}

Это или создайте фактический Startup и пусть его использует строитель:

var builder = new HostBuilder()
    .UseStartup<Startup>()
    //...omitted for brevity
...