Skip to content

Commit 69bd245

Browse files
committed
Merge branch 'develop'
2 parents 7fd5cb9 + cdfd49c commit 69bd245

File tree

69 files changed

+3397
-1398
lines changed

Some content is hidden

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

69 files changed

+3397
-1398
lines changed

CSharp/Documentation/Forms.cs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
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
17+
/// [ChoiceLastSeparator]: @ref Advanced.TemplateBaseAttribute.ChoiceLastSeparator
18+
/// [ChoiceSeparator]: @ref Advanced.TemplateBaseAttribtue.ChoiceSeparator
1619
/// [ChoiceFormat]: @ref Advanced.TemplateBaseAttribute.ChoiceFormat
20+
/// [ChoiceParens]: @ref Advanced.TemplateBaseAttribute.ChoiceParens
1721
/// [ChoiceStyle]: @ref Advanced.TemplateBaseAttribute.ChoiceStyle
1822
/// [Feedback]: @ref Advanced.TemplateBaseAttribute.Feedback
1923
/// [FieldCase]: @ref Advanced.TemplateBaseAttribute.FieldCase
@@ -414,7 +418,7 @@
414418
/// ~~~{.txt}
415419
/// What kind of sandwich would you like?
416420
/// > ?
417-
/// * You are filling in the sandwich field.Possible responses:
421+
/// * You are filling in the sandwich field. Possible responses:
418422
/// * You can enter in any words from the descriptions. (BLT, Black Forest Ham, Buffalo Chicken, Chicken And Bacon Ranch Melt, Cold Cut Combo, Meatball Marinara, Over Roasted Chicken, Roast Beef, Rotisserie Style Chicken, Spicy Italian, Steak And Cheese, Sweet Onion Teriyaki, Tuna, Turkey Breast, and Veggie)
419423
/// * Back: Go back to the previous question.
420424
/// * Help: Show the kinds of responses you can enter.
@@ -720,12 +724,16 @@
720724
/// Usage | Description
721725
/// ------|------------
722726
/// [AllowDefault] | When processing choices using {\|\|} controls whether the current value should be showed as a choice.
723-
/// [ChoiceFormat] | When processing choices using {\|\|} controls how each choice is formatted. {0} is the choice number and {1} the choice description.
727+
/// [ChoiceCase] | When prcoessing choices for {\|\|} controls case normalization for each choice.
728+
/// [ChoiceFormat] | When processing choices for {\|\|} controls how each choice is formatted. {0} is the choice number and {1} the choice description.
729+
/// [ChoiceLastSeparator] | When inline choice lists are constructed for {\|\|} provides the separator before the last choice.
730+
/// [ChoiceParens] | When inline choice lists are constructed for {\|\|} indicates whether or not they are in parentheses.
731+
/// [ChoiceSeparator] | When inline choice lists are constructed for {\|\|} provides the separaotr before every choice except the last.
724732
/// [ChoiceStyle] | When processing choices using {\|\|} controls whether the choices are presented in line or per line.
725733
/// [Feedback] | For [Prompt] only controls feedback after user entry.
726734
/// [FieldCase] | Controls case normalization when displaying a field description.
727-
/// [LastSeparator] | When lists are constructed for {[]} or in line choices from {\|\|} provides the separator before the last item.
728-
/// [Separator] | When lists are constructed for {[]} or in line choices from {\|\|} provides the separator before every item except the last.
735+
/// [LastSeparator] | When lists are constructed for {[]} provides the separator before the last item.
736+
/// [Separator] | When lists are constructed for {[]} provides the separator before every item except the last.
729737
/// [ValueCase] | Controls case normalization when displaying a field value.
730738
///
731739
}

CSharp/Library/Dialogs/BotToUser.cs

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,55 @@
1-
using Microsoft.Bot.Builder.Internals.Fibers;
2-
using Microsoft.Bot.Connector;
1+
//
2+
// Copyright (c) Microsoft. All rights reserved.
3+
// Licensed under the MIT license.
4+
//
5+
// Microsoft Bot Framework: http://botframework.com
6+
//
7+
// Bot Builder SDK Github:
8+
// https://github.com/Microsoft/BotBuilder
9+
//
10+
// Copyright (c) Microsoft Corporation
11+
// All rights reserved.
12+
//
13+
// MIT License:
14+
// Permission is hereby granted, free of charge, to any person obtaining
15+
// a copy of this software and associated documentation files (the
16+
// "Software"), to deal in the Software without restriction, including
17+
// without limitation the rights to use, copy, modify, merge, publish,
18+
// distribute, sublicense, and/or sell copies of the Software, and to
19+
// permit persons to whom the Software is furnished to do so, subject to
20+
// the following conditions:
21+
//
22+
// The above copyright notice and this permission notice shall be
23+
// included in all copies or substantial portions of the Software.
24+
//
25+
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
26+
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27+
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28+
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29+
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30+
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31+
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32+
//
33+
334
using System;
35+
using System.Collections;
436
using System.Collections.Generic;
37+
using System.IO;
538
using System.Linq;
639
using System.Text;
740
using System.Threading;
841
using System.Threading.Tasks;
9-
using System.Collections;
42+
43+
using Microsoft.Bot.Builder.Internals.Fibers;
44+
using Microsoft.Bot.Connector;
1045

1146
namespace Microsoft.Bot.Builder.Dialogs.Internals
1247
{
13-
public sealed class ReactiveBotToUser : IBotToUser
48+
public sealed class SendLastInline_BotToUser : IBotToUser
1449
{
1550
private readonly Message toBot;
1651
private readonly IConnectorClient client;
17-
public ReactiveBotToUser(Message toBot, IConnectorClient client)
52+
public SendLastInline_BotToUser(Message toBot, IConnectorClient client)
1853
{
1954
SetField.NotNull(out this.toBot, nameof(toBot), toBot);
2055
SetField.NotNull(out this.client, nameof(client), client);
@@ -95,4 +130,26 @@ async Task IBotToUser.PostAsync(Message message, CancellationToken cancellationT
95130
this.queue.Enqueue(message);
96131
}
97132
}
133+
134+
public sealed class BotToUserTextWriter : IBotToUser
135+
{
136+
private readonly IBotToUser inner;
137+
private readonly TextWriter writer;
138+
public BotToUserTextWriter(IBotToUser inner, TextWriter writer)
139+
{
140+
SetField.NotNull(out this.inner, nameof(inner), inner);
141+
SetField.NotNull(out this.writer, nameof(writer), writer);
142+
}
143+
144+
Message IBotToUser.MakeMessage()
145+
{
146+
return this.inner.MakeMessage();
147+
}
148+
149+
async Task IBotToUser.PostAsync(Message message, CancellationToken cancellationToken)
150+
{
151+
await this.inner.PostAsync(message, cancellationToken);
152+
await this.writer.WriteLineAsync(message.Text);
153+
}
154+
}
98155
}

CSharp/Library/Dialogs/Chain.cs

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,30 @@ public static IDialog<R> ContinueWith<T, R>(this IDialog<T> antecedent, Continut
103103
return new ContinueWithDialog<T, R>(antecedent, continuation);
104104
}
105105

106+
/// <summary>
107+
/// When the antecedent <see cref="IDialog{T}"/> has completed, project the result into a new <see cref="IDialog{R}"/>.
108+
/// </summary>
109+
/// <typeparam name="T">The type of the antecedent dialog.</typeparam>
110+
/// <typeparam name="R">The type of the projected dialog.</typeparam>
111+
/// <param name="antecedent">The antecedent dialog <see cref="IDialog{T}"/>.</param>
112+
/// <param name="selector">The projection function from <typeparamref name="T"/> to <typeparamref name="R"/>.</param>
113+
/// <returns>The result <see cref="IDialog{R}"/>.</returns>
114+
public static IDialog<R> Select<T, R>(this IDialog<T> antecedent, Func<T, R> selector)
115+
{
116+
return new SelectDialog<T, R>(antecedent, selector);
117+
}
118+
119+
/// <summary>
120+
/// When the antecedent <see cref="IDialog{IDialog{T}}"/> has completed, unwrap the result into a new <see cref="IDialog{T}"/>.
121+
/// </summary>
122+
/// <typeparam name="T">The type of the antecedent dialog.</typeparam>
123+
/// <param name="antecedent">The antecedent dialog <see cref="IDialog{IDialog{T}}"/>.</param>
124+
/// <returns>The result <see cref="IDialog{T}"/>.</returns>
125+
public static IDialog<T> Unwrap<T>(this IDialog<IDialog<T>> antecedent)
126+
{
127+
return new UnwrapDialog<T>(antecedent);
128+
}
129+
106130
/// <summary>
107131
/// When the antecedent <see cref="IDialog{T}"/> has completed, execute the next <see cref="IDialog{C}"/>, and use the projection to combine the results.
108132
/// </summary>
@@ -123,9 +147,9 @@ public static IDialog<R> SelectMany<T, C, R>(this IDialog<T> antecedent, Func<T,
123147
/// </summary>
124148
/// <param name="antecedent">The antecedent <see cref="IDialog"/>.</param>
125149
/// <returns>The looping dialog.</returns>
126-
public static IDialog Loop(this IDialog antecedent)
150+
public static IDialog<T> Loop<T>(this IDialog<T> antecedent)
127151
{
128-
return new LoopDialog(antecedent);
152+
return new LoopDialog<T>(antecedent);
129153
}
130154

131155
[Serializable]
@@ -136,7 +160,7 @@ public FromDialog(Func<IDialog<T>> MakeDialog)
136160
{
137161
SetField.NotNull(out this.MakeDialog, nameof(MakeDialog), MakeDialog);
138162
}
139-
async Task IDialog.StartAsync(IDialogContext context)
163+
async Task IDialog<T>.StartAsync(IDialogContext context)
140164
{
141165
var dialog = this.MakeDialog();
142166
context.Call<T>(dialog, ResumeAsync);
@@ -157,7 +181,7 @@ public DoDialog(IDialog<T> antecedent, Action<IAwaitable<T>> Action)
157181
SetField.NotNull(out this.Antecedent, nameof(antecedent), antecedent);
158182
SetField.NotNull(out this.Action, nameof(Action), Action);
159183
}
160-
async Task IDialog.StartAsync(IDialogContext context)
184+
async Task IDialog<T>.StartAsync(IDialogContext context)
161185
{
162186
context.Call<T>(this.Antecedent, ResumeAsync);
163187
}
@@ -176,7 +200,7 @@ public PostToUserDialog(IDialog<T> antecedent)
176200
{
177201
SetField.NotNull(out this.Antecedent, nameof(antecedent), antecedent);
178202
}
179-
async Task IDialog.StartAsync(IDialogContext context)
203+
async Task IDialog<T>.StartAsync(IDialogContext context)
180204
{
181205
context.Call<T>(this.Antecedent, ResumeAsync);
182206
}
@@ -198,7 +222,7 @@ public ContinueWithDialog(IDialog<T> antecedent, Continutation<T, R> continuatio
198222
SetField.NotNull(out this.Antecedent, nameof(antecedent), antecedent);
199223
SetField.NotNull(out this.Continuation, nameof(continuation), continuation);
200224
}
201-
async Task IDialog.StartAsync(IDialogContext context)
225+
async Task IDialog<R>.StartAsync(IDialogContext context)
202226
{
203227
context.Call<T>(this.Antecedent, ResumeAsync);
204228
}
@@ -213,6 +237,52 @@ private async Task DoneAsync(IDialogContext context, IAwaitable<R> result)
213237
}
214238
}
215239

240+
[Serializable]
241+
private sealed class SelectDialog<T, R> : IDialog<R>
242+
{
243+
public readonly IDialog<T> Antecedent;
244+
public readonly Func<T, R> Selector;
245+
public SelectDialog(IDialog<T> antecedent, Func<T, R> selector)
246+
{
247+
SetField.NotNull(out this.Antecedent, nameof(antecedent), antecedent);
248+
SetField.NotNull(out this.Selector, nameof(selector), selector);
249+
}
250+
async Task IDialog<R>.StartAsync(IDialogContext context)
251+
{
252+
context.Call<T>(this.Antecedent, AfterAntecedent);
253+
}
254+
private async Task AfterAntecedent(IDialogContext context, IAwaitable<T> result)
255+
{
256+
var itemT = await result;
257+
var itemR = this.Selector(itemT);
258+
context.Done(itemR);
259+
}
260+
}
261+
262+
[Serializable]
263+
private sealed class UnwrapDialog<T> : IDialog<T>
264+
{
265+
public readonly IDialog<IDialog<T>> Antecedent;
266+
public UnwrapDialog(IDialog<IDialog<T>> antecedent)
267+
{
268+
SetField.NotNull(out this.Antecedent, nameof(antecedent), antecedent);
269+
}
270+
async Task IDialog<T>.StartAsync(IDialogContext context)
271+
{
272+
context.Call<IDialog<T>>(this.Antecedent, AfterAntecedent);
273+
}
274+
private async Task AfterAntecedent(IDialogContext context, IAwaitable<IDialog<T>> result)
275+
{
276+
var dialogT = await result;
277+
context.Call<T>(dialogT, AfterDialog);
278+
}
279+
private async Task AfterDialog(IDialogContext context, IAwaitable<T> result)
280+
{
281+
var itemT = await result;
282+
context.Done(itemT);
283+
}
284+
}
285+
216286
// http://blogs.msdn.com/b/pfxteam/archive/2013/04/03/tasks-monads-and-linq.aspx
217287
[Serializable]
218288
private sealed class SelectManyDialog<T, C, R> : IDialog<R>
@@ -226,7 +296,7 @@ public SelectManyDialog(IDialog<T> antecedent, Func<T, IDialog<C>> function, Fun
226296
SetField.NotNull(out this.Function, nameof(function), function);
227297
SetField.NotNull(out this.Projection, nameof(projection), projection);
228298
}
229-
async Task IDialog.StartAsync(IDialogContext context)
299+
async Task IDialog<R>.StartAsync(IDialogContext context)
230300
{
231301
context.Call<T>(this.Antecedent, AfterAntecedent);
232302
}
@@ -246,20 +316,20 @@ private async Task AfterFunction(IDialogContext context, IAwaitable<C> result)
246316
}
247317

248318
[Serializable]
249-
private sealed class LoopDialog : IDialog
319+
private sealed class LoopDialog<T> : IDialog<T>
250320
{
251-
public readonly IDialog Antecedent;
252-
public LoopDialog(IDialog antecedent)
321+
public readonly IDialog<T> Antecedent;
322+
public LoopDialog(IDialog<T> antecedent)
253323
{
254324
SetField.NotNull(out this.Antecedent, nameof(antecedent), antecedent);
255325
}
256-
async Task IDialog.StartAsync(IDialogContext context)
326+
async Task IDialog<T>.StartAsync(IDialogContext context)
257327
{
258-
context.Call<object>(this.Antecedent, ResumeAsync);
328+
context.Call<T>(this.Antecedent, ResumeAsync);
259329
}
260-
private async Task ResumeAsync(IDialogContext context, IAwaitable<object> ignored)
330+
private async Task ResumeAsync(IDialogContext context, IAwaitable<T> ignored)
261331
{
262-
context.Call<object>(this.Antecedent, ResumeAsync);
332+
context.Call<T>(this.Antecedent, ResumeAsync);
263333
}
264334
}
265335
}

0 commit comments

Comments
 (0)