У меня есть проект функций Azure, который использует внедрение зависимостей (Startup.cs
внедряет службы на основе разных интерфейсов). Те службы, которые реализуют интерфейсы, также используют внедрение зависимостей конструктора.
В одной из этих реализаций я хочу вызвать метод для Durable Entity, но я предпочитаю не делать часть DurableEntityClient
сигнатуры метода (поскольку в других реализациях EntityClient может вообще не понадобиться). Поэтому я надеялся увидеть, что IDurableEntityClient
вводится в конструктор моего класса.
Но оказывается, что значение равно null
. Хотите знать, поддерживается ли это и осуществимо ли это? (чтобы иметь дружественный к DI способ внедрения классов, которые хотят получить EntityClient для среды выполнения функций, в которой они работают)
Некоторые фрагменты кода:
Startup.cs
builder.Services.AddSingleton<IReceiver, TableReceiver>();
Фактическая функция
public class ItemWatchHttpTrigger
{
private IReceiver _receiver;
public ItemWatchHttpTrigger(IReceiver receiver)
{
_receiver = receiver;
}
[FunctionName("item-watcher")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "item/{itemId}")]
HttpRequest request, string itemId, [DurableClient] IDurableEntityClient client, ILogger logger)
{
// Actual implementation
}
}
Ссылочный класс
public class TableReceiver : IReceiver
{
private IDurableEntityClient _entityClient;
public TableReceiver(IDurableEntityClient client)
{
_entityClient = client; // client is null :(
}
}
Я согласен, что это был бы обходной путь, но мне он не нравится, поскольку я считаю, что IDurableEntityClient
является частью реализации и не должен быть частью объявления интерфейса. Лучше всего будет что-то вроде DurableEntityClient.GetFromContext()
в SDK.
Не уверен, так как я не использовал его, но кажется, что вы можете внедрить IDurableClientFactory
через services.AddDurableTask();
и получить/создать новый IDurableClient
клиент. IDurableClient
наследуется от IDurableEntityClient
. Смотрите здесь. Проверьте, можете ли вы вызвать метод, предоставленный IDurableEntityClient
, для полученного объекта с фабрики.
Да, я как раз собирался опубликовать это как ответ, так как получил это в ответ на мою проблему с github. Выпишет. TX
Основываясь на ответе на мою проблему с github, кажется, что это можно внедрить в автозагрузку, поскольку 2.4.0
версия пакета Microsoft.Azure.WebJobs.Extensions.DurableTask
:
Некоторые фрагменты кода:
Startup.cs
builder.Services.AddSingleton<IReceiver, TableReceiver>();
builder.Services.AddDurableClientFactory();
Ссылочный класс
public class TableReceiver : IReceiver
{
private IDurableEntityClient _entityClient;
public TableReceiver(IDurableClientFactory entityClientFactory, IConfiguration configuration)
{
_entityClient = entityClientFactory.CreateClient(new DurableClientOptions
{
TaskHub = configuration["TaskHubName"]
});
}
}
Это хорошо работает, спасибо! Хотя я не думаю, что вы хотели передать IDurableEntityClient
в параметрах, поскольку в этом случае он не используется и по-прежнему равен нулю.
Спасибо, Мюррей, ты прав. Будет обновлен образец кода.
IDurableEntityClient
привязывается как параметр привязки. Я не думаю, что вы можете использовать инъекцию в конструкторе через DI. Вы можете предоставить метод в методеIReceiver
для принятияIDurableEntityClient
, который может быть передан вызывающимIReceiver
.