Официальный пример Microsoft, который обеспечивает языковой перевод в промежуточном программном обеспечении в боте, кажется, обеспечивает языковой перевод, который запускается в промежуточном программном обеспечении 3 различными способами.
Мой вопрос: почему 3 разных типа / способа не перекрываются? (Как триггеры являются взаимоисключающими?)
Код, о котором идет речь, живет здесь
Три раза, как кажется, срабатывает:
1) if (turnContext.Activity.Type == ActivityTypes.Message) //trigger translation
2) turnContext.OnSendActivities(async (newContext, activities, nextSend) => //trigger translation
3) turnContext.OnUpdateActivity(async (newContext, activity, nextUpdate) => //trigger translation
Отдельный вопрос, который может помочь внести ясность -> Документация гласит ... "остерегайтесь короткого замыкания" вашего промежуточного ПО, но не ясно, как одно мое (преднамеренно или случайно) замкнуло его промежуточное ПО , Замкнут ли промежуточное ПО одно из следующих двух операторов возврата?
return await nextSend(); //LINE 83 at time of writing
return await nextUpdate(); //LINE 100 at time of writing
Для потомков ссылочный код:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
namespace Microsoft.BotBuilderSamples.Translation
{
/// <summary>
/// Middleware for translating text between the user and bot.
/// Uses the Microsoft Translator Text API.
/// </summary>
public class TranslationMiddleware : IMiddleware
{
private readonly MicrosoftTranslator _translator;
private readonly IStatePropertyAccessor<string> _languageStateProperty;
/// <summary>
/// Initializes a new instance of the <see cref="TranslationMiddleware"/> class.
/// </summary>
/// <param name="translator">Translator implementation to be used for text translation.</param>
/// <param name="languageStateProperty">State property for current language.</param>
public TranslationMiddleware(MicrosoftTranslator translator, UserState userState)
{
_translator = translator ?? throw new ArgumentNullException(nameof(translator));
if(userState == null)
{
throw new ArgumentNullException(nameof(userState));
}
_languageStateProperty = userState.CreateProperty<string>("LanguagePreference");
}
/// <summary>
/// Processes an incoming activity.
/// </summary>
/// <param name="turnContext">Context object containing information for a single turn of conversation with a user.</param>
/// <param name="next">The delegate to call to continue the bot middleware pipeline.</param>
/// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken = default(CancellationToken))
{
if (turnContext == null)
{
throw new ArgumentNullException(nameof(turnContext));
}
var translate = await ShouldTranslateAsync(turnContext, cancellationToken);
if (translate)
{
if (turnContext.Activity.Type == ActivityTypes.Message)
{
turnContext.Activity.Text = await _translator.TranslateAsync(turnContext.Activity.Text, TranslationSettings.DefaultLanguage, cancellationToken);
}
}
turnContext.OnSendActivities(async (newContext, activities, nextSend) =>
{
string userLanguage = await _languageStateProperty.GetAsync(turnContext, () => TranslationSettings.DefaultLanguage) ?? TranslationSettings.DefaultLanguage;
bool shouldTranslate = userLanguage != TranslationSettings.DefaultLanguage;
// Translate messages sent to the user to user language
if (shouldTranslate)
{
List<Task> tasks = new List<Task>();
foreach (Activity currentActivity in activities.Where(a => a.Type == ActivityTypes.Message))
{
tasks.Add(TranslateMessageActivityAsync(currentActivity.AsMessageActivity(), userLanguage));
}
if (tasks.Any())
{
await Task.WhenAll(tasks).ConfigureAwait(false);
}
}
return await nextSend();
});
turnContext.OnUpdateActivity(async (newContext, activity, nextUpdate) =>
{
string userLanguage = await _languageStateProperty.GetAsync(turnContext, () => TranslationSettings.DefaultLanguage) ?? TranslationSettings.DefaultLanguage;
bool shouldTranslate = userLanguage != TranslationSettings.DefaultLanguage;
// Translate messages sent to the user to user language
if (activity.Type == ActivityTypes.Message)
{
if (shouldTranslate)
{
await TranslateMessageActivityAsync(activity.AsMessageActivity(), userLanguage);
}
}
return await nextUpdate();
});
await next(cancellationToken).ConfigureAwait(false);
}
private async Task TranslateMessageActivityAsync(IMessageActivity activity, string targetLocale, CancellationToken cancellationToken = default(CancellationToken))
{
if (activity.Type == ActivityTypes.Message)
{
activity.Text = await _translator.TranslateAsync(activity.Text, targetLocale);
}
}
private async Task<bool> ShouldTranslateAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
string userLanguage = await _languageStateProperty.GetAsync(turnContext, () => TranslationSettings.DefaultLanguage, cancellationToken) ?? TranslationSettings.DefaultLanguage;
return userLanguage != TranslationSettings.DefaultLanguage;
}
}
}