对于FormFlow IDialog ,是否需要Chain.From(Is Chain.From Required for FormFlow IDialog)

示例,如SandwichBot,使用Chain.From返回SendAsync的IDialog<T> ,如下所示:

internal static IDialog<SandwichOrder> MakeRootDialog() { return Chain.From(() => FormDialog.FromForm(SandwichOrder.BuildForm)); }

我可以看到Chain.From推送并弹出从FormDialog.FromForm返回的IFormDialog<T> ,但我不确定它的好处是什么。 但是,聊天机器人仍然可以在没有Chain.From情况下Chain.From ,如下所示:

internal static IDialog<SandwichOrder> MakeRootDialog() { return FormDialog.FromForm(SandwichOrder.BuildForm); }

由于这些示例使用Chain.From ,因此我认为它可能以某种方式需要或推荐。 Chain.From的基本原理是Chain.From ,它需要在哪里,没有它的简单语法有什么缺点?

Examples, like SandwichBot, use Chain.From to return the IDialog<T> for SendAsync, like this:

internal static IDialog<SandwichOrder> MakeRootDialog() { return Chain.From(() => FormDialog.FromForm(SandwichOrder.BuildForm)); }

I can see that Chain.From pushes and pops the IFormDialog<T>, returned from FormDialog.FromForm, but am not sure what the benefit of that is. However, the chatbot still works without Chain.From, as shown below:

internal static IDialog<SandwichOrder> MakeRootDialog() { return FormDialog.FromForm(SandwichOrder.BuildForm); }

Since the examples use Chain.From, it makes me think that it might be somehow required or recommended. What is the rationale for Chain.From, where would it be required, and what are the drawbacks to the simpler syntax without it?

最满意答案

在SimpleSandwichBot中,我认为拥有Chain.From是没有意义的,但是我怀疑这样做是为了允许无缝过渡到AnnotatedSandwichBot ,其中Chain被更多地使用。

我个人不会使用Chain除非我需要把一些非常简单的东西放在一起,我不想创建一个对话框,因为它很容易变得复杂,无法阅读/遵循。

使用Chain您可以隐式管理对话框堆栈。 但是,对堆栈的显式管理( 使用Call / Done )似乎更适合编写更大的对话。 创建新的对话框更加冗长(特别是在C# ),但我相信它可以更好地组织解决方案和代码。

我不认为有一个需要Chain的地方因为它没有提供任何独特的东西,只是一个可用于LINQ查询语法的流畅界面。

我看到的缺点主要在于如果你想要创建一些大的东西,结果代码的复杂性。 如果我没记错,根据您的使用方式,也有可能出现序列化问题。

来自文档 :

Chain方法为LINQ查询语法中可用的对话提供了流畅的接口。 LINQ查询语法的编译形式通常利用匿名方法。 如果这些匿名方法不引用局部变量的环境,那么这些匿名方法没有状态,并且可以简单地序列化。 但是,如果匿名方法捕获环境中的任何局部变量,则生成的闭包对象(由编译器生成)不会标记为可序列化。 Bot Builder将检测到这种情况并抛出ClosureCaptureException以帮助诊断问题。

In the SimpleSandwichBot I believe that it doesn't make sense to have the Chain.From, however I suspect that was done to allow a seamless transition to the AnnotatedSandwichBot where the Chain is being used a bit more.

Personally I don't use Chain a lot unless I need to put together something really simple and I don't want to create a dialog as it could easily become complex to read/follow.

With Chain you can manage the stack of dialogs implicitly. However, explicit management of the stack of dialogs (using Call/Done) seems to be better to composing larger conversations. Creating new dialogs it's more verbose (especially in C#) but I believe it allows to organize better the solution and the code.

I don't think there is a place where Chain is required as it's not providing anything unique, just a fluent interface that is usable in LINQ query syntax.

The drawbacks I see are mainly around complexity of the resulting code if you are trying to create something big. If I don't misremember, there is also a chance of getting a serialization issue depending how you are using it.

From the docs:

The Chain methods provide a fluent interface to dialogs that is usable in LINQ query syntax. The compiled form of LINQ query syntax often leverages anonymous methods. If these anonymous methods do not reference the environment of local variables, then these anonymous methods have no state and are trivially serializable. However, if the anonymous method captures any local variable in the environment, the resulting closure object (generated by the compiler) is not marked as serializable. The Bot Builder will detect this situation and throw a ClosureCaptureException to help diagnose the issue.

更多推荐