Skip to content

Commit 057c954

Browse files
committed
Merge branch 'develop'
2 parents 57b1b4e + e81b9dd commit 057c954

File tree

81 files changed

+7512
-3852
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+7512
-3852
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

CSharp/Documentation/Dialogs.cs

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@
117117
///
118118
/// \section IDialogContext
119119
/// All of the dialogs take in an IDialogContext, an interface that provides the services
120-
/// needed to save state and comunicate.
120+
/// needed to save state and communicate.
121121
/// The interface is composed of three interfaces: Internals.IBotData, Internals.IDialogStack, and Internals.IBotToUser.
122122
///
123123
/// Internals.IBotData represents access to the per user, conversation, and user in conversation state maintained
@@ -136,6 +136,84 @@
136136
/// - Wait for a message from the user and suspend the conversation until the message arrives.
137137
/// The stack is usually automatically managed for you.
138138
///
139+
/// \section Serialization
140+
///
141+
/// The dialog stack and the state of all active dialog are serialized to the per-user, per-conversation IBotDataBag. This serialized blob is persisted through
142+
/// the Messages sent to and received from the %Bot Connector. Dialog classes must be marked with the serializable attribute so that Dialog object instances
143+
/// can participate in the runtime serialization. For example, all of the IDialog implementations in the builder library are marked as serializable.
144+
/// When custom serialization was desired, there is an ISerialization implementation and serialization constructor as well.
145+
///
146+
/// 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.
147+
/// 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
148+
/// 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
149+
/// will detect this situation and throw a ClosureCaptureException to help diagnose the issue.
150+
///
151+
/// If you wish to try to leverage reflection to serialize classes that are not marked as serializable, the library has a reflection-based serialization surrogate that
152+
/// can be registered with Autofac as follows:
153+
///
154+
/// \dontinclude Microsoft.Bot.Builder.Tests\ChainTests.cs
155+
/// \skip includeReflection
156+
/// \until }
157+
///
158+
/// \section Fluent Dialog Chains
159+
///
160+
/// Explicit management of the stack of active dialogs is possible through IDialogStack.Call<R> and IDialogStack.Done<R>, explicitly composing dialogs into a larger
161+
/// conversation. It is also possible to implicitly manage the stack of active dialogs through the fluent Chain methods.
162+
///
163+
/// Here is an overview of the chain methods, followed by some examples.
164+
///
165+
/// Name | Type | Notes
166+
/// ----- | ---- | -----
167+
/// Chain.Select<T, R> | Linq | Supports "select" and "let" in linq query syntax.
168+
/// Chain.SelectMany<T, C, R> | Linq | Supports successive "from" in linq query syntax.
169+
/// Chain.Where<T> | Linq | Supports "where" in linq query syntax.
170+
/// Chain.From<T> | Chains | Instantiates a new instance of a dialog.
171+
/// Chain.Return<T> | Chains | Return a constant value into the chain.
172+
/// Chain.Do<T> | Chains | Allow for side-effects within the chain.
173+
/// Chain.ContinueWith<T, R> | Chains | Simple chaining of dialogs.
174+
/// Chain.Unwrap<T> | Chains | Unwrap a dialog nested in a dialog.
175+
/// Chain.Loop<T> | Branch | Loop the entire chain of dialogs.
176+
/// Chain.Switch<T, R> | Branch | Support branching into different dialog chains.
177+
/// Chain.PostToUser<T> | Message | Post a message to the user.
178+
/// Chain.WaitToBot<T> | Message | Wait for a message to the bot.
179+
/// Chain.PostToChain<T> | Message | Start a chain with a message from the user.
180+
///
181+
/// These Chain methods fall into a few buckets.
182+
///
183+
/// Linq query syntax starts off with the basic Chain.Select<T, R>:
184+
///
185+
/// \dontinclude Microsoft.Bot.Builder.Tests\ChainTests.cs
186+
/// \skip MakeSelectQuery
187+
/// \skip query
188+
/// \until select
189+
///
190+
/// and linq query syntax is enhanced with support for Chain.SelectMany<T, C, R>:
191+
///
192+
/// \dontinclude Microsoft.Bot.Builder.Tests\ChainTests.cs
193+
/// \skip LinqQuerySyntax_Without_Reflection_Surrogate
194+
/// \skip query
195+
/// \until select
196+
///
197+
/// Posting messages from the bot to the user and vice versa are supported by a Chain.PostToUser<T> and Chain.WaitToBot<T>:
198+
///
199+
/// \dontinclude Microsoft.Bot.Builder.Tests\ChainTests.cs
200+
/// \skip PostToUser
201+
/// \until PostToUser
202+
///
203+
/// Branching conversation dialog flow is supported by Chain.Switch<T, R>:
204+
///
205+
/// \dontinclude Microsoft.Bot.Builder.Tests\ChainTests.cs
206+
/// \skip logic
207+
/// \until );
208+
///
209+
/// If Chain.Switch<T, R> returns a nested IDialog<IDialog<T>>, then the inner IDialog<T> can be unwrapped with Chain.Unwrap<T>. This allows for branching
210+
/// in conversations to different paths of chained dialogs, possibly of unequal length. Here is a more complete example of branching dialogs written
211+
/// in the fluent chain style with implicit stack management:
212+
///
213+
/// \dontinclude Microsoft.Bot.Builder.Tests\ChainTests.cs
214+
/// \skip joke
215+
/// \until Loop
216+
///
139217
/// \section Conclusion
140218
/// Through this description we have seen how you can easily create stateless bots that can reuse dialog building blocks
141219
/// ranging from simple prompts to advanced natural language. As a next step, you should explore \ref forms which

CSharp/Documentation/Forms.cs

Lines changed: 74 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
/// [EntityRecommendation.Entity]: @ref Microsoft.Bot.Builder.Luis.EntityRecommendation.Entity
1414
/// [LuisDialog]: @ref Microsoft.Bot.Builder.Dialogs.LuisDialog
1515
/// [AllowDefault]: @ref Advanced.TemplateBaseAttribute.AllowDefault
16-
/// [ChoiceCase]: @ref Advanvced.TemplateBaseAttribute.ChoiceCase
16+
/// [ChoiceCase]: @ref Advanced.TemplateBaseAttribute.ChoiceCase
1717
/// [ChoiceLastSeparator]: @ref Advanced.TemplateBaseAttribute.ChoiceLastSeparator
18-
/// [ChoiceSeparator]: @ref Advanced.TemplateBaseAttribtue.ChoiceSeparator
18+
/// [ChoiceSeparator]: @ref Advanced.TemplateBaseAttribute.ChoiceSeparator
1919
/// [ChoiceFormat]: @ref Advanced.TemplateBaseAttribute.ChoiceFormat
2020
/// [ChoiceParens]: @ref Advanced.TemplateBaseAttribute.ChoiceParens
2121
/// [ChoiceStyle]: @ref Advanced.TemplateBaseAttribute.ChoiceStyle
@@ -112,7 +112,7 @@
112112
/// * Back: Go back to the previous question.
113113
/// * Help: Show the kinds of responses you can enter.
114114
/// * Quit: Quit the form without completing it.
115-
/// * Reset: Start over filling in the form. (With defaults of your previous entries.)
115+
/// * Reset: Start over filling in the form. (With defaults from your previous entries.)
116116
/// * Status: Show your progress in filling in the form so far.
117117
/// * You can switch to another field by entering its name. (Sandwich, Length, Bread, Cheese, Toppings, and Sauce).
118118
/// ~~~
@@ -423,7 +423,7 @@
423423
/// * Back: Go back to the previous question.
424424
/// * Help: Show the kinds of responses you can enter.
425425
/// * Quit: Quit the form without completing it.
426-
/// * Reset: Start over filling in the form. (With defaults of your previous entries.)
426+
/// * Reset: Start over filling in the form. (With defaults from your previous entries.)
427427
/// * Status: Show your progress in filling in the form so far.
428428
/// * You can switch to another field by entering its name. (Sandwich, Length, Bread, Cheese, Sauces, and Toppings).
429429
/// ~~~
@@ -564,7 +564,7 @@
564564
/// For sandwich toppings you have selected Avocado, Banana Peppers, Cucumbers, Green Bell Peppers, Lettuce, Olives, Pickles, Red Onion, Spinach, and Tomatoes.
565565
/// ~~~
566566
///
567-
/// \subsection ControlFlow Using the Form Builder
567+
/// \subsection controlFlow Using the Form Builder
568568
/// So far we have improved your dialog via attributes and business logic. There is
569569
/// another way to improve your dialog and that is through the FormBuilder. The FormBuilder
570570
/// allows more fine-grained control over the steps in your conversation and lets you put in messages
@@ -573,31 +573,82 @@
573573
/// is explicit navigation.) Here is a more complex usage of FormBuilder:
574574
/// \dontinclude AnnotatedSandwichBot/AnnotatedSandwich.cs
575575
/// \skip static
576-
/// \until return
576+
/// \until .Build
577577
/// \until }
578578
///
579-
/// The steps this defines are:
580-
/// * Show the welcome message
581-
/// * Fill in SandwichOrder.Sandwich
579+
/// This looks complex, but that is because of the addition of advanced features like validation and dynamically defined fields.
580+
/// (See \ref dynamicFields for more information.)
581+
/// The main structure is all about defining the default step order. Here are the steps:
582+
/// * Show the welcome message.
583+
/// * Fill in SandwichOrder.Sandwich
582584
/// * Fill in SandwichOrder.Length
583585
/// * Fill in SandwichOrder.Bread
584586
/// * Fill in SandwichOrder.Cheese
585587
/// * Fill in SandwichOrder.Toppings
586-
/// * Show a message confirming the selected toppings.
588+
/// * Show a message confirming the selected toppings.
589+
/// * Fill in SandwichOrder.Sauces
590+
/// * Dynamically defined field for SandwichOrder.Specials. (See \ref dynamicFields for more information.)
591+
/// * Dynamically defined confirmation for the cost
587592
/// * Fill in SandwichOrder.DeliveryAddress and verify the resulting string. If it does not start with a number we return a message.
588593
/// * Fill in SandwichOrder.DeliveryTime with a custom prompt.
589594
/// * Confirm the order.
590595
/// * Add any remaining fields in the order they are defined in your class. (If this was left out, those steps to fill in those fields would not be included.)
591-
/// * Show a final message thanking them.
596+
/// * Show a final thank you message.
597+
/// * Define an OnCompletionAsync handler to process the order.
592598
///
593599
/// In the SandwichOrder.DeliveryTime prompt and the confirmation message you can see an instance of
594600
/// the \ref patterns where pattern elements like {Length} are filled in from your C# class
595601
/// before the string is shown to the user.
596602
///
603+
/// \subsection dynamicFields Dynamically Defined Fields, Confirmations and Messages
597604
/// FormBuilder also allows you to do other more advanced things like dynamically switch on
598605
/// and off parts of your form based on the state of your object or dynamically define fields
599606
/// rather than drive them off a C# class.
600607
///
608+
/// In order to define a dynamic field, you can implement Advanced.IField yourself,
609+
/// but it is easier to make use of the Advanced.FieldReflector class. Imagine we would like to
610+
/// create some specials for free drinks and cookies but only for foot-long sandwiches.
611+
/// The first step for using Advanced.FieldReflector is to define
612+
/// the underlying field that will contain your dynamic value, like this:
613+
/// \dontinclude AnnotatedSandwichBot/AnnotatedSandwich.cs
614+
/// \skip Sauces
615+
/// \skip Optional
616+
/// \until Specials
617+
///
618+
/// We can apply normal attributes to this field like [Optional] to mark the field as allowing a no preference choice and by changing the template
619+
/// value for TemplateUsage.NoPreference.
620+
///
621+
/// Now we need to add the dynamic part to the FormBuilder like this:
622+
/// \dontinclude AnnotatedSandwichBot/AnnotatedSandwich.cs
623+
/// \skip nameof(Specials)
624+
/// \until }))
625+
///
626+
/// There are a couple of pieces here:
627+
/// * Advanced.Field.SetType sets the type of the field--in this case null which means enumeration.
628+
/// * Advanced.Field.SetActive provides a delegate that enables the field only when the length is a foot long.
629+
/// * Advanced.Field.SetDefine provides an async delegate for defining the field. The delegate is passed the current state object and also the Advanced.Field that is being dynamically defined.
630+
/// The delegate uses the fluent methods found on the field to dynamically define values. In this case we define values as strings and supply the descriptions and terms for the value.
631+
///
632+
/// Messages and confirmations can also be defined dynamically. Messages and confirmations only run when the prior steps are inactive
633+
/// or are completed. This is a confirmation that computes the cost of the sandwich:
634+
/// \dontinclude AnnotatedSandwichBot/AnnotatedSandwich.cs
635+
/// \skip Confirm
636+
/// \until })
637+
///
638+
/// \subsection quitExceptions Handling Quit and Exceptions
639+
/// When the user types 'quit' or there is an exception while filling in a form using FormDialog it is useful to be able
640+
/// to know what step the 'quit' or exception happened, the state of the form and and what steps were successfully completed.
641+
/// All of these are passed back through the FormCanceledException<T> class. Here is an example of how to catch the exception and send
642+
/// a message after either:
643+
/// * Successfully processing the order.
644+
/// * When the user quit.
645+
/// * When there is an exception.
646+
/// \dontinclude AnnotatedSandwichBot/Controllers/MessagesController.cs
647+
/// \skip MakeRootDialog
648+
/// \until });
649+
/// \until }
650+
///
651+
/// \subsection finalBot Final Sandwich Bot
601652
/// Here is the final SandwichOrder with attributes, business logic and a more complex form.
602653
/// \include AnnotatedSandwichBot/AnnotatedSandwich.cs
603654
///
@@ -623,15 +674,15 @@
623674
/// 15. Veggie
624675
/// > 2
625676
/// What size of sandwich do you want? (1. Six Inch, 2. Foot Long)
626-
/// > 1
677+
/// > 2
627678
/// What kind of bread would you like on your sandwich?
628679
/// 1. Nine Grain Wheat
629680
/// 2. Nine Grain Honey Oat
630681
/// 3. Italian
631682
/// 4. Italian Herbs And Cheese
632683
/// 5. Flatbread
633684
/// > nine grain
634-
/// By "nine grain" bread did you mean(1. Nine Grain Honey Oat, 2. Nine Grain Wheat)
685+
/// By "nine grain" bread did you mean (1. Nine Grain Honey Oat, 2. Nine Grain Wheat)
635686
/// > 1
636687
/// What kind of cheese would you like on your sandwich? (current choice: No Preference)
637688
/// 1. American
@@ -654,7 +705,7 @@
654705
/// > everything but jalapenos
655706
/// For sandwich toppings you have selected Avocado, Banana Peppers, Cucumbers, Green Bell Peppers, Lettuce, Olives, Pickles, Red Onion, Spinach, and Tomatoes.
656707
///
657-
/// Please select one or more sauces(current choice: No Preference)
708+
/// Please select one or more sauces (current choice: No Preference)
658709
/// 1. Honey Mustard
659710
/// 2. Light Mayonnaise
660711
/// 3. Regular Mayonnaise
@@ -665,15 +716,22 @@
665716
/// 8. Sweet Onion
666717
/// 9. Vinegar
667718
/// >
719+
/// What kind of specials would you like on your sandwich? (current choice: None)
720+
/// 1. Free cookie
721+
/// 2. Free large drink
722+
/// > 1
723+
/// Total for your sandwich is $6.50 is that ok?
724+
/// > y
668725
/// Please enter delivery address
669726
/// > 123 State Street
670727
/// What time do you want your sandwich delivered? (current choice: No Preference)
671-
/// > 4:30
672-
/// Do you want to order your Six Inch Black Forest Ham on Nine Grain Honey Oat bread with Pepperjack, Avocado, Banana Peppers, Cucumbers, Green Bell Peppers, Lettuce, Olives, Pickles, Red Onion, Spinach, and Tomatoes to be sent to 123 State Street at 4:30 PM?
728+
/// > 4:30pm
729+
/// Do you want to order your Foot Long Black Forest Ham on Nine Grain Honey Oat bread with Pepperjack, Avocado, Banana Peppers, Cucumbers, Green Bell Peppers, Lettuce, Olives, Pickles, Red Onion, Spinach, and Tomatoes to be sent to 123 State Street at 4:30 PM?
673730
/// > y
674731
/// Please enter a number between 1.0 and 5.0 for your experience today(current choice: No Preference)
675732
/// > 5
676733
/// Thanks for ordering a sandwich!
734+
/// Processed your order!
677735
/// ~~~
678736
///
679737
/// \section initialState Passing in Initial Form State and Entities

CSharp/Documentation/Overview.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ namespace Microsoft.Bot.Builder.Dialogs
4040
/// \skip Interactive
4141
/// \until while
4242
/// \until }
43+
/// \until }
4344
///
4445
/// To use it your would do something like this:
4546
/// ~~~
46-
/// Interactive(FormDialog.FromForm<AnnotatedSandwichOrder>(() => AnnotatedSandwichOrder.BuildForm()));
47+
/// Interactive(FormDialog.FromForm<AnnotatedSandwichOrder>(() => AnnotatedSandwichOrder.BuildForm())).GetAwaiter().GetResult();
4748
/// ~~~
4849
///
4950
/// \section troubleshooting_q_and_a Troubleshooting Q & A

CSharp/Library/Dialogs/BotData.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ bool IBotDataBag.TryGetValue<T>(string key, out T value)
141141
value = default(T);
142142
return false;
143143
}
144+
145+
bool IBotDataBag.RemoveValue(string key)
146+
{
147+
return this.bag.Remove(key);
148+
}
144149
}
145150

146151
protected override IBotDataBag WrapData(Dictionary<string, object> data)
@@ -192,6 +197,11 @@ bool IBotDataBag.TryGetValue<T>(string key, out T value)
192197
value = default(T);
193198
return false;
194199
}
200+
201+
bool IBotDataBag.RemoveValue(string key)
202+
{
203+
return this.bag.Remove(key);
204+
}
195205
}
196206

197207
protected override IBotDataBag WrapData(JObject data)

CSharp/Library/Dialogs/BotToUser.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,8 @@
3131
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3232
//
3333

34-
using System;
35-
using System.Collections;
3634
using System.Collections.Generic;
3735
using System.IO;
38-
using System.Linq;
39-
using System.Text;
4036
using System.Threading;
4137
using System.Threading.Tasks;
4238

0 commit comments

Comments
 (0)