Можно ли получить текущее имя шага диалога? - PullRequest
0 голосов
/ 01 апреля 2020

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

public abstract class BaseDialog : ComponentDialog
{
    private static Dictionary<string, string> StepHelp = new Dictionary<string, string>();
    protected static void AddStepHelp(string function, string text)
    {
        StepHelp.Add(function, text);
    }
    private async Task<DialogTurnResult> InterruptAsync(DialogContext innerDc, CancellationToken cancellationToken)
    {
        Activity helpMessage;
        string curStepName = ""; //???
        if (userText == "help" && StepHelp.ContainsKey(curStepName))
        {
            helpMessage = MessageFactory.Text(StepHelp[curStepName], StepHelp[curStepName], InputHints.ExpectingInput);
        }
        await innerDc.Context.SendActivityAsync(helpMessage, cancellationToken);
    }
}

Затем я добавляю текст в диалоге chidl:

public class MyChildDialog: BaseDialog
{
    static MyChildDialog()
    {
        AddStepHelp(nameof(Step1), "Help text for step1");
    }
    public MyChildDialog()
    {
        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
        {
            Step1
        }));
        InitialDialogId = nameof(WaterfallDialog);
    }
    private async Task<DialogTurnResult> Step1(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {

    }
}

Вы можете увидеть в приведенной выше функции InterruptAsyn c я вызываю словарь для получения справочного сообщения в базовом диалоге, но как мне получить имя текущего шага?

Ответы [ 2 ]

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

Хотя индекс шага легко получить, как объяснил Билловертон, получить имя шага сложно. Поле _steps является закрытым, как и метод, который возвращает имя шага , поэтому вы не сможете получить доступ к шагам, даже если ваш класс наследуется от WaterfallDialog. Имена шагов открываются только через клиент телеметрии, поэтому вы можете написать собственный клиент телеметрии, который каким-то образом предоставляет информацию вашему боту, но в этот момент, вероятно, проще использовать отражение для доступа к закрытым членам.

Поскольку вы действительно хотите, чтобы имя шага использовалось в качестве ключа для вашего словаря, просто использовать вместо этого индекс шага - гораздо лучший вариант. Вы можете использовать Dictionary<int, string>, но имеет смысл использовать List<string>, если вы хотите иметь строку помощи для каждого шага в водопаде.

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

Вы можете получить текущий шаг index , а также имя диалога, так что вы сможете создать уникальный идентификатор из этой информации (если вы не назвали все диалоги) waterfallDialog "из примера, как я сделал!). Я использую нод, но предполагаю, что получение данных из вашего stepContext похоже или одинаково.

  • Имя диалога можно найти по адресу stepContext.stack[stepContext.stack.length-1].id.
  • Шаг Индекс может быть найден в stepContext.stack[stepContext.stack.length-1].state.stepIndex.

Я не могу вспомнить, можете ли вы в итоге получить вложенные диалоги внутри диалога водопада. Я знаю, что ваш главный / внешний контекст будет иметь весь стек, но я думаю у вас всегда будет только один элемент внутри вашего конкретного водопада. Тем не менее, текущий диалог должен быть последним в стеке, поэтому доступ к нему как stepContext.stack.length-1 должен работать в любом случае. В случае, если текущий диалог находится в элементе 0, очевидно, вы можете просто получить к нему доступ как таковой.

Пока имена диалогов вашего водопада уникальны, вы получите идентификаторы, такие как waterfallDialog0, waterfallDialog1, et c. что вы могли бы затем сопоставить в своем словаре, чтобы помочь текстам.

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

getInnermostActiveDialog(dc) {
    var child = dc.child;

    return child ? this.getInnermostActiveDialog(child) : dc.activeDialog;
}

, где dc - ваш внешний контекст диалога. Я не углубился в это, но вы сможете получить те же значения id и stepIndex.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...