Как создать класс экземпляра QnA Maker в C# - CoreBot? - PullRequest
1 голос
/ 21 апреля 2020

Я получил System.AggregateException после запуска образца Core Bot C#.

В Startup.cs я добавил класс следующим образом:

     services.AddSingleton<ChitChatRecognizer>();

Класс Recognizer выглядит как:

    using System.Net.Http;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Bot.Builder;
    using Microsoft.Bot.Builder.AI.QnA;
    using Microsoft.Bot.Schema;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;

    namespace CoreBot
    {
        public class ChitChatRecognizer : ActivityHandler
        {

            private readonly IConfiguration _configuration;
            private readonly ILogger<ChitChatRecognizer> _logger;
            private readonly IHttpClientFactory _httpClientFactory;

            public ChitChatRecognizer(IConfiguration configuration, ILogger<ChitChatRecognizer> logger, IHttpClientFactory httpClientFactory)
            {
                _configuration = configuration;
                _logger = logger;
                _httpClientFactory = httpClientFactory;
            }

            protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
            {
                var httpClient = _httpClientFactory.CreateClient();

                var qnaMaker = new QnAMaker(new QnAMakerEndpoint
                {
                    KnowledgeBaseId = _configuration["QnAKnowledgebaseId"],
                    EndpointKey = _configuration["QnAEndpointKey"],
                    Host = _configuration["QnAEndpointHostName"]
                },
                null,
                httpClient);

                _logger.LogInformation("Calling QnA Maker");

                var options = new QnAMakerOptions { Top = 1 };

                // The actual call to the QnA Maker service.
                var response = await qnaMaker.GetAnswersAsync(turnContext, options);
                if (response != null && response.Length > 0)
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text(response[0].Answer), cancellationToken);
                }
                else
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text("No QnA Maker answers were found."), cancellationToken);
                }
            }
        }
    }

Я еще даже не использую класс, но не могу даже запустить свою программу без ошибки. Что мне делать?

ErrorCode:

"Некоторые службы не могут быть построены (Ошибка при проверке дескриптора службы 'ServiceType: CoreBot.ChitChatRecognizer. .ChitChatRecognizer ': не удается разрешить службу для типа' System. Net .Http.IHttpClientFactory 'при попытке активировать' CoreBot.ChitChatRecognizer '.) (Ошибка при проверке дескриптора службы' ServiceType: Microsoft.BotBuilderSamples.Dialogs.MainDialog). Тип реализации Singleton: Microsoft.BotBuilderSamples.Dialogs.MainDialog: невозможно разрешить службу для типа «Система. Net .Http.IHttpClientFactory» при попытке активировать «CoreBot.ChitChatRecognizer».) (Ошибка при проверке дескриптора службы «ServiceType» : Microsoft.Bot.Builder.IBot Время жизни: переходный тип реализации: Microsoft.BotBuilderSamples.Bots.DialogAndWelcomeBot`1 [Microsoft.BotBuilderSamples.Dialogs.MainDialog] ': невозможно разрешить службу для типа' S ystem. Net .Http.IHttpClientFactory 'при попытке активировать' CoreBot.ChitChatRecognizer '.) "

1 Ответ

1 голос
/ 22 апреля 2020

Ваши настройки странные ... вы делаете ChitChatRecognizer, который является ботом (он происходит от ActivityHandler), а затем, позже, DI превращается в диалог или в другого бота, я так понимаю? Также кажется, что вы хотите рассматривать QnAMaker (распознаватель QnA) как одиночный, но инициализируете его в OnMessageActivityAsync - это означает, что он не будет инициализирован, если ваш бот не получит сообщение, поэтому, если вы пытаетесь инициализировать что-то еще требует QnAMaker, его не будет при запуске.


В любом случае, чтобы ответить на вопрос, как вставить QnAMaker в corebot, если вы хотите добавить QnAMaker как синглтон, вы можете добавить его как синглтон при запуске, а затем вызывать его из своего кода бота, когда вам нужно позвонить в QnAMaker.

Добавить QnAMaker в Corebot Sample

In Startup.ConfigureServices:

// Register QnAMaker recognizer
services.AddSingleton<MyQnaMaker>();

MyQnAMaker.cs

namespace Microsoft.BotBuilderSamples
{
    public class MyQnaMaker
    {
        public MyQnaMaker(IConfiguration configuration)
        {
            ChitChatRecognizer = new QnAMaker(new QnAMakerEndpoint
            {
                KnowledgeBaseId = configuration["QnAKnowledgebaseId"],
                EndpointKey = configuration["QnAEndpointKey"],
                Host = configuration["QnAEndpointHostName"]
            });
        }

        public QnAMaker ChitChatRecognizer { get; set; }
    }
}

Конструктор DialogAndWelcomeBot.cs

DI QnAMaker в бот

        public DialogAndWelcomeBot(ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger, MyQnaMaker myQnAMaker)
            : base(conversationState, userState, dialog, logger, myQnAMaker)

DialogBot.cs

        public DialogBot(ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger, MyQnaMaker qnaMaker)
        {
            ConversationState = conversationState;
            UserState = userState;
            Dialog = dialog;
            Logger = logger;
            MyQnaMaker = qnaMaker;
        }

...

        protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            Logger.LogInformation("Running dialog with Message Activity.");

            if (turnContext.Activity.Text == "yo")
            {
                await CallQnAMaker(turnContext, cancellationToken);
            } else {
                // Run the Dialog with the new message Activity.
                await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
            }

        }

        private async Task CallQnAMaker(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var options = new QnAMakerOptions { Top = 1 };

            // The actual call to the QnA Maker service.
            var response = await MyQnaMaker.ChitChatRecognizer.GetAnswersAsync(turnContext, options);
            if (response != null && response.Length > 0)
            {
                await turnContext.SendActivityAsync(MessageFactory.Text(response[0].Answer), cancellationToken);
            }
            else
            {
                await turnContext.SendActivityAsync(MessageFactory.Text("No QnA Maker answers were found."), cancellationToken);
            }
        }

Добавить еще для ваших классов по мере необходимости, это просто минимум. Выше в DialogBot.cs вы можете видеть, что у меня есть триггер для вызова QnAMaker, если пользователь вводит "yo" в качестве сообщения, для целей тестирования.


Запуск Corebot

enter image description here


Альтернативы

В качестве альтернативы вы можете просто new поднять новый QnAMaker в обработчике сообщений бота (например, DialogBot.OnMessageActivityAsync()), аналогично тому, как это сделано в примере 11.qnamaker, и избавьтесь от синглтона.

...