【发布时间】:2019-10-11 10:04:35
【问题描述】:
我的机器人的功能之一是处理购物车。用户可以在对话中的任意位置添加商品,然后完成购物以关闭产品购物车。
为了避免将购物车从一个对话框传递到另一个对话框,我想在UserState 中创建一个UserProfile 属性(UserProfile 属性有一个ShoppingCart 属性)但我不太清楚如何使用这是正确的。
我的主对话框包含一组子对话框,其中一些需要能够访问ShoppingCart 对象。我在示例中找到了一些示例,但它们都没有达到我想要的效果。在状态管理示例中:
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// Get the state properties from the turn context.
var conversationStateAccessors = _conversationState.CreateProperty<ConversationData>(nameof(ConversationData));
var conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationData());
var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));
var userProfile = await userStateAccessors.GetAsync(turnContext, () => new UserProfile());
if (string.IsNullOrEmpty(userProfile.Name))
{
// First time around this is set to false, so we will prompt user for name.
if (conversationData.PromptedUserForName)
{
// Set the name to what the user provided.
userProfile.Name = turnContext.Activity.Text?.Trim();
// Acknowledge that we got their name.
await turnContext.SendActivityAsync($"Thanks {userProfile.Name}. To see conversation data, type anything.");
// Reset the flag to allow the bot to go though the cycle again.
conversationData.PromptedUserForName = false;
}
else
{
// Prompt the user for their name.
await turnContext.SendActivityAsync($"What is your name?");
// Set the flag to true, so we don't prompt in the next turn.
conversationData.PromptedUserForName = true;
}
}
如果我理解正确,每次他想要获取访问器时都会创建一个新属性?或者,如果您调用CreateProperty,一旦创建了一个属性,就不会创建任何属性并返回访问器?
我曾考虑在 Bot 上获取访问器,然后将其传递给 MainDialog,然后传递给 ChildDialogs,但这有点违背了不通过对话框传递 ShoppingCart 的目的。
我不能在每次都创建一个属性的情况下获取访问器吗?
我已阅读 this issue,它为我的问题提供了解决方案,但后来我看到 @johnataylor 的评论说
我们遵循的模式是将访问器的创建推迟到我们需要它时——这似乎最有效地隐藏了固有的噪音。
如果我想在我的对话框中获取ShoppingCart(在我需要访问的UserProfile 属性中),我应该何时创建访问器?
【问题讨论】:
标签: c# asp.net-core botframework accessor