Внедрение зависимостей для связующего ПО для чат-ботов Azure? - PullRequest
0 голосов
/ 21 мая 2018

Я работаю над новым чат-ботом, использующим Azure Bot Service и QnAMaker.Мы используем промежуточное ПО BotBuilder, включая пользовательское промежуточное ПО, для настройки поведения бота.

Одна из промежуточных программ будет вызывать функцию Azure, и я хотел бы использовать новую функцию HttpClientFactory с пользовательским промежуточным ПО, ноэто требует внедрения зависимостей.

Как я могу использовать внедрение зависимостей в промежуточном программном обеспечении BotBuilder, как вы делаете это с обычным промежуточным программным обеспечением .NET Core?

Когда вы смотрите на конфигурацию бота в Startup.cs , вы можете видеть, как требуется new для всех зависимостей бота:

services.AddHttpClient<MyFunctionClient>(client =>
{
    client.BaseAddress = new Uri(mySettings.GetValue<string>("myFunctionUrl"));
    client.DefaultRequestHeaders.Add("x-functions-key", mySettings.GetValue<string>("myFunctionKey"));
});

services.AddBot<QnAMakerBot>(options =>
{  
    options.CredentialProvider = new ConfigurationCredentialProvider(Configuration);

    options.ConnectorClientRetryPolicy = new RetryPolicy(
        new BotFrameworkHttpStatusCodeErrorDetectionStrategy(),
        3,
        TimeSpan.FromSeconds(2), 
        TimeSpan.FromSeconds(20),
        TimeSpan.FromSeconds(1));

    var middleware = options.Middleware;
    middleware.Add(new ConversationState<ChatLog>(new MemoryStorage()));
    middleware.Add(new MyCustomMiddleware()); // <- I want to inject a typed HttpClient here

//... etc. ....

Есть ли другой способ настройкибот, который позволяет вводить зависимости?

Если для MyCustomMiddleware требуется набрать HttpClient в своем конструкторе, я должен создать новый экземпляр прямо здесь, так что я не получаю преимущества DI иЯ только что настроил конфигурацию.

1 Ответ

0 голосов
/ 21 мая 2018

Хотя я не фанат шаблона поиска сервисов, текущий дизайн конфигурации бота не очень удобен для внедрения зависимостей.

Использование характера настройки промежуточного программного обеспечения бота, но необходимость предоставления новогоНапример, во время запуска я обошел следующую работу:

public class BotMiddlewareAdapter<TMiddleware> : IMiddleware
    where TMiddleware : IMiddleware {
    private readonly Lazy<TMiddleware> middleware;

    public BotMiddlewareAdapter(IServiceCollection services) {
        middleware = new Lazy<TMiddleware>(() =>
            services.BuildServiceProvider().GetRequiredService<TMiddleware>());
    }

    public Task OnTurn(ITurnContext context, MiddlewareSet.NextDelegate next) {
        return middleware.Value.OnTurn(context, next);
    }
}

Он принимает IServiceCollection в качестве явной зависимости и откладывает создание поставщика услуг и возможное разрешение фактического промежуточного программного обеспечения на фабрике.делегат.

Затем он может быть реализован с использованием

middleware.Add(new BotMiddlewareAdapter<MyCustomMiddleware>(services));

. Когда вызывается адаптер, он лениво разрешает намеченное промежуточное ПО при первоначальном вызове, а затем вызывает его.

ВФактически, вы можете сделать еще один шаг и преобразовать его в метод расширения

public static class BotBuilderMiddlewareExtension {
    public static void Add<TMiddleware>(this IList<IMiddleware> middleware, IServiceCollection services) 
        where TMiddleware : IMiddleware {
        middleware.Add(new BotMiddlewareAdapter<TMiddleware>(services));
    }
}

, который упрощает настройку до

middleware.Add<MyCustomMiddleware>(services);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...