【发布时间】:2020-11-27 03:39:50
【问题描述】:
在 Microsoft BotFramework v4 中,您通常将状态(UserState、ConversationState、PrivateConversationState)传播到对话框通过将它们作为参数传递给它的构造函数。
这边:
Startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// ...
IStorage storage = new MemoryStorage(); // For testing only !
services.AddSingleton(new UserState(storage));
services.AddSingleton(new ConversationState(storage));
// ...
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
services.AddSingleton<GoviiBaseDialog>(x => new RootDialog(
x.GetRequiredService<UserState>(),
x.GetRequiredService<ConversationState>()
);
services.AddTransient<IBot, Bot<RootDialog>>();
}
}
Bot.cs
public class Bot<T> : ActivityHandler where T : Dialog
{
T _dialog;
BotState _userState, _conversationState;
public Bot(T dialog, UserState userState, ConversationState conversationState,)
{
_userState = userState;
_conversationState = conversationState;
_dialog = dialog;
}
public override async Task OnTurnAsync(ITurnContext context, CancellationToken cancellationToken = default)
{
await base.OnTurnAsync(context, cancellationToken);
await _userState.SaveChangesAsync(context);
await _conversationState.SaveChangesAsync(context);
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> context, CancellationToken cancellationToken)
{
await _dialog.RunAsync(context, _conversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}
}
RootDialog.cs
public class RootDialog : ComponentDialog
{
UserState _userState;
ConversationState _conversationState;
public RootDialog(UserState uState, ConversationState cState) : base("id")
{
_userState = uState;
_conversationState = cState;
// Add some dialogs and pass states as parameters
AddDialog(new CustomDialog_1(uState, cState));
AddDialog(new CustomDialog_2(uState, cState));
// ...
AddDialog(new CustomDialog_N(uState, cState));
}
}
现在让我们假设那些 CustomDialogs 再次使用其他一些需要访问状态的 CustomDialogs。状态必须一次又一次地作为参数传递给构造函数。
问题是:是否有另一种方法来访问状态以避免一次又一次地作为参数传递?
【问题讨论】:
-
这可能是一个 XY 问题,所以你能解释一下为什么你想将机器人状态传递给你的对话框吗?我认为将特定的机器人状态访问器传递给对话框而不是机器人状态本身是有意义的,但我知道这不会改变您问题的性质。
-
我认为传递 BotState 而不是访问器的原因是因为我还是 BF v4 的新手,对它不是很熟悉。我将在接下来的几天重构我的代码并更新问题。但是,是的,这不会改变我的问题的性质。
-
我还发现this说通过状态是可以的。那么传递整个状态而不是访问器有缺点吗?
-
没有客观的缺点,只有潜在的主观缺点取决于你喜欢如何设计你的机器人。但这并不重要。一旦出现在对话框中,我仍然需要知道您想要使用状态来跟踪什么。
-
我使用状态来跟踪识别的实体和用户输入的位置等。我需要将这些东西保存在某个地方以供以后处理。
标签: botframework