2017-04-11 44 views
-1

我有一个需要重置或杀死(使用context.Done)当前的IDialogContext实例,并创建一个新的实例,并在不同的功能中使用它。我如何创建这样一个实例,IDialogContext是一个接口。可能吗?如何在Microsoft Bot框架中创建一个新的IDialogContext实例?

这是从我试图调用一个函数 “selfredirect”

private async Task ApprovalConfirm(IDialogContext context, IAwaitable<IMessageActivity> result) 
{ 
var message = await result; 
xxxticket xxxticketobject = new xxxticket(); 
if (message.Text.Contains("yes")) 
{ 
    xxxticketobject = context.ConversationData.Get<xxxticket>("xxxcard"); 
    if (xxxticketobject.action == "Approve") 
     await context.PostAsync("Accepted"); 
    else 
     await context.PostAsync("Rejected"); 
    context.ConversationData.RemoveValue("xxxfinalcard"); 
    context.Reset();// *This is what I want to do...clear context and then call the following function* 
    await SelfRedirect(context, context.UserData.Get<string>("CurrentQuery"), "Approval"); 
} 
else if (message.Text == "no") 
{ 
    await context.PostAsync("Thank you"); 
    context.Done(context); 
} 
else 
    await SelfRedirect(context, context.UserData.Get<string>("CurrentQuery"), null); 

}

的selfredirect功能

public static async Task SelfRedirect(IDialogContext context, string msg, string intent=null) 
    { 
     try 
     { 
      DialogLuis LUISDialog = new DialogLuis(); 
      IMessageActivity message = context.MakeMessage(); 
      message.Text = msg; 
      var tasks = LUISDialog.services.Select(s => s.QueryAsync(message.Text, context.CancellationToken)).ToArray(); 
      var results = await Task.WhenAll(tasks); 
      var winners = from result in results.Select((value, index) => new { value, index }) 
          let resultWinner = LUISDialog.BestIntentFrom(result.value) 
          where resultWinner != null 
          select new LuisServiceResult(result.value, resultWinner, LUISDialog.services[result.index]); 
      if (intent != null) 
      { 
       winners = from result in results.Select((value, index) => new { value, index }) 
          let resultWinner = new IntentRecommendation(intent) 
          where resultWinner != null 
          select new LuisServiceResult(result.value, resultWinner, LUISDialog.services[result.index]); 
      } 
      var winner = LUISDialog.BestResultFrom(winners); 
      if (winner == null) 
      { 
       throw new InvalidOperationException("No winning intent selected from Luis results."); 
      } 
      if (winner.Result.Dialog?.Status == DialogResponse.DialogStatus.Question) 
      { 
       var childDialog = await LUISDialog.MakeLuisActionDialog(winner.LuisService, 
                  winner.Result.Dialog.ContextId, 
                  winner.Result.Dialog.Prompt); 
       context.Call(childDialog, LUISDialog.LuisActionDialogFinished); 
      } 
      else 
      { 
       IAwaitable<IMessageActivity> item = null; 
       await LUISDialog.DispatchToIntentHandler(context, item, winner.BestIntent, winner.Result); 
      } 
     } 
     catch (Exception ex) { CommonMethods.LogTime("", ex, context); } 
    } 

的功能,但我不能用当堆栈为空时,重置后的重定向功能。请帮助

让我解释我为什么通过这个小小的功能

private async Task ApprovalConfirm(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 
     var message = await result; 
     if (message.Text == "no") 
     { 
      await context.PostAsync("Thank you"); 
      context.Done(context); 
     } 
     else if (message.Text == "yes") 
     { 
      await context.PostAsync("yes"); 
      context.Done(context); 
     } 
     else 
     { 
      context.Wait(MessageReceived); 
     } 
    } 

我的使用情况是喜欢用selfredirect函数而不是context.wait(的messageReceived),如果用户类型是那么机器人应返回yes,如果用户输入no,那么bot应该返回谢谢。并且如果用户键入“Hi”,机器人应该通过路易斯找到Hi的答案,这将打到新的问候意图并返回Hi用户。

在这里,如果我的用户context.Wait(的messageReceived),那么机器人将只需等待下一个查询从用户

对话框的结构!

[LuisIntent("Approval")] 
    public async Task Approval(IDialogContext context, LuisResult result) 
    { 
     context.ConversationData.SetValue("currentIntent", "Approval"); 
     . 
     . 
     . 
     PromptDialog.Choice<string>(context, ApprovalList, ...); 
    } 


private async Task ApprovalList(IDialogContext context, IAwaitable<string> result) 
    { 
     try 
     { 
      var request_type = await result; 
      . 
      . 
      context.Wait(ApprovalResponse); 
      } 
     } 
     catch (Exception ex) 
     { 
      CommonMethods.LogTime("ApprovalList", ex, context); 
     } 
    } 
private async Task ApprovalResponse(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 
     var message = await result; 
     . 
     . 
     . 
      context.Wait(AfterApprovalComment); 
     } 
     catch (Exception ex) 
     { 
      CommonMethods.LogTime("ApprovalResponse", ex, context); 
      await context.PostAsync("out of approvals..."); 
      context.Done(context); 
     } 
    } 


private async Task ApprovalConfirm(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 
     var message = await result; 
     . 
     . 
     . 
    await SelfRedirect(context, context.UserData.Get<string>("CurrentQuery"), "Approval"); 
    } 
+0

我想要在当前函数中创建的实例。因为我正在处理多个对话框,最后我需要将它重定向到一个不同的函数,该函数也需要一个Idialogcontext实例 –

+0

请显示您的代码,否则很难理解您要做什么。 –

+0

@EzequielJadib嗨我已经添加了代码.. :) –

回答

0

根据讨论,我们在评论中了解更多您的要求,似乎您不需要重置堆栈。

相反,您需要做的是利用您从继承的LuisDialog中的MessageReceived方法。通过这样做,您可以直接调用该方法并强制它去LUIS解决新的意图,而不需要用户的新输入。

调用该方法与调用其他方法完全相同。唯一需要注意的是,由于MessageReceived方法期望得到IAwaitable<IMessageActivity>,因此您必须创建该方法。好消息是,使用Awaitable.FromItem