示例,例如SandwichBot,使用Chain.From
返回IDialog<T>
SendAsync
,如下所示:
internal static IDialog<SandwichOrder> MakeRootDialog()
{
return Chain.From(() => FormDialog.FromForm(SandwichOrder.BuildForm));
}
我可以看到Chain.From
推送并弹出从IFormDialog<T>
返回的FormDialog.FromForm
,但我不确定它的好处是什么。但是,聊天机器人仍可以使用Chain.From
,如下所示:
internal static IDialog<SandwichOrder> MakeRootDialog()
{
return FormDialog.FromForm(SandwichOrder.BuildForm);
}
由于示例使用Chain.From
,因此我认为它可能以某种方式需要或推荐。 Chain.From
的基本原理是什么,它需要在哪里,没有它的简单语法会有什么缺点?
答案 0 :(得分:1)
在SimpleSandwichBot中我认为拥有Chain.From
没有意义,但我怀疑是为了能够无缝过渡到AnnotatedSandwichBot Chain
1}}正在使用更多。
我个人不会经常使用Chain
,除非我需要把一些非常简单的东西放在一起,而且我不想创建一个对话框,因为它很容易变得难以阅读/跟随。
使用Chain
,您可以隐式管理对话框堆栈。但是,对堆栈(using Call/Done)的显式管理似乎更适合组成更大的对话。创建新的对话框更加冗长(特别是在C#
中),但我相信它可以更好地组织解决方案和代码。
我认为不存在需要Chain
的地方,因为它没有提供任何独特的东西,只是一个可用于LINQ
查询语法的流畅界面。
我看到的缺点主要在于如果你想要创建一些大的东西,那么结果代码的复杂性。如果我没记错,根据您的使用方式,也有可能出现序列化问题。
来自docs:
Chain方法为LINQ查询语法中可用的对话提供了流畅的接口。 LINQ查询语法的编译形式通常利用匿名方法。如果这些匿名方法不引用局部变量的环境,那么这些匿名方法没有状态,并且可以简单地序列化。但是,如果匿名方法捕获环境中的任何局部变量,则生成的闭包对象(由编译器生成)不会标记为可序列化。 Bot Builder将检测到这种情况并抛出ClosureCaptureException来帮助诊断问题。