Невозможно заставить внедрение работать в функции Azure, когда у службы есть другие зависимости - PullRequest
1 голос
/ 15 марта 2020

У меня есть услуга CompanyService

Эта услуга зависит от 2 других служб - ICompanyRepository и IDataCacheService

public class CompanyService : ICompanyService
{
    private readonly ICompanyRepository _companyRepository;
    private IDataCacheService _dataCacheService;

    public CompanyService(ICompanyRepository companyRepository, IDataCacheService dataCacheService)
    {
        _companyRepository = companyRepository;
        _dataCacheService = dataCacheService;
    }
}

Сами эти службы не имеют зависимостей

Теперь мне нужно сделать это доступным через встроенную инъекцию в моей Azure функции

, поэтому в Startup.cs я изменил Configure, чтобы добавить новые сервисы

public override void Configure(IFunctionsHostBuilder builder)
{
    var cosmosDbConnectionString = new CosmosDBConnectionString(Environment.GetEnvironmentVariable("CosmosDBConnection"));
    builder.Services.AddSingleton<IDocumentClient>(s =>
       new DocumentClient(cosmosDbConnectionString.ServiceEndpoint, cosmosDbConnectionString.AuthKey));

    var companyRepository = new CompanyRepository();
    builder.Services.AddSingleton<ICompanyRepository>(companyRepository);

    var dataCacheService = new DataCacheService();
    builder.Services.AddSingleton<IDataCacheService>(dataCacheService);

    var companyService = new CompanyService(companyRepository, dataCacheService);

    builder.Services.AddSingleton<ICompanyService>(companyService);
}

Это компилируется и выполняется через

Однако, когда я добавляю ICompanyService в качестве параметра моей функции, я получаю ошибку

Невозможно связать параметр 'companyService' для ввода ICompanyService

Мой метод ниже

public class Companies
{
    private const string OperationName = "OPERATION";

    [FunctionName(OperationName)]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = "myroute/")]HttpRequest req,
        ICompanyService companyService,
        ILogger log)
    {
       //logic here
    }
}

Это так же, как другие методы запуска функции в моем проекте

Что я сделано неправильно?

Это также не работает со стандартным синтаксисом AddSingleton

builder.Services.AddSingleton<ICompanyService, CompanyService>();

Пол

1 Ответ

2 голосов
/ 15 марта 2020

Учитывая показанную конфигурацию, регистрацию можно упростить до

public override void Configure(IFunctionsHostBuilder builder) {
    var services = builder.Services;
    var cosmosDbConnectionString = new CosmosDBConnectionString(Environment.GetEnvironmentVariable("CosmosDBConnection"));
    services.AddSingleton<IDocumentClient>(s =>
       new DocumentClient(cosmosDbConnectionString.ServiceEndpoint, cosmosDbConnectionString.AuthKey));

    services.AddSingleton<ICompanyRepository, CompanyRepository>();        
    services.AddSingleton<IDataCacheService, DataCacheService>();    
    services.AddSingleton<ICompanyService, CompanyService>();
}

Все, что осталось, - это убедиться в том, что вы явно ввели нужную услугу в экземпляр функции через внедрение конструктора.

public class Companies {
    private const string OperationName = "OPERATION";
    private readonly ICompanyService companyService;

    public Companies(ICompanyService companyService) {
        this.companyService = companyService;
    }

    [FunctionName(OperationName)]
    public async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", Route = "myroute/")]HttpRequest req,
        ILogger log) {
       //logic here
    }
}

Ссылка Использовать внедрение зависимостей. NET Azure Функции

...