Search code examples
botframeworkbots

MessageReceivedAsync calls without argument


I have this very basic question about calls to MessageReceivedAsync. I understand this method is called from context.Wait. However, what I want to clarify is how is the function called without passing on any arguments. The method definition has 2 arguments.

    public Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);

        return Task.CompletedTask;
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    { 
    var activity = await result as Activity;
}

Solution

  • Rahul, this is actually a somewhat complicated question. I'll try to explain as best I can and point you to the code you can examine to get a deeper understanding if you desire.

    context.Wait(MessageReceivedAsync) is calling the Wait method of the IDialogContext which is defined as..

     public static void Wait(this IDialogStack stack, ResumeAfter<IMessageActivity> resume)
    

    As you can see, this is an extension method of IDialogStack. The important thing to see here is the second parameter ResumeAfter. ResumeAfter is a delgate for what to do when the Wait event occurs, which is usually someone typing a new message to your bot.

    Ok, now we can look at the definition of the delegate ResumeAfter. It is defined as...

    public delegate Task ResumeAfter<in T>(IDialogContext context, IAwaitable<T> result);
    

    and there's your answer. The parameters for MessageReceivedAsync are a result of the delegate ResumeAfter. The values of the parameters are defined by and setup by the bot framework. I hope this gave you a better understanding of what's happening behind the scenes with a MS bot. This code is all contained on GitHub in Microsoft's BotBuilder source The specific code file I'm references is IDialogContext.cs located here.