Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I resolve the current dialog stack in my Bot Framework MessagesController?

In my Messages controller, I want to check whether a certain dialog is on the stack for the incoming message prior to dispatching it to a dialog, so that I can suppress certain conditional behavior. I tried resolving IDialogStack as per this answer, like so:

public async Task<HttpResponseMessage> Post([FromBody] Activity incomingMessage)
    {
        try
        {
            if (incomingMessage.Type == ActivityTypes.Message)
            {
                using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
                {
                    var stack = scope.Resolve<IDialogStack>();
                }
                ...

Here's the modules being registered in my Global.asax:

    private void RegisterBotModules()
    {
        var builder = new ContainerBuilder();

        builder.RegisterModule(new DialogModule());
        builder.RegisterModule(new ReflectionSurrogateModule());
        builder.RegisterModule(new DialogModule_MakeRoot());

        builder.RegisterModule<GlobalMessageHandler>();

        builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));

        var store = new TableBotDataStore(/*connection string*/);
        builder.Register(c => store)
            .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
            .AsSelf()
            .SingleInstance();

        builder.Register(c => new CachingBotDataStore(store, CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency))
            .As<IBotDataStore<BotData>>()
            .AsSelf()
            .InstancePerLifetimeScope();

        builder.Update(Conversation.Container);
        var config = GlobalConfiguration.Configuration;
        config.DependencyResolver = new AutofacWebApiDependencyResolver(Conversation.Container);
    }

However, I get the following Exception:

{"An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = IDialogTask (DelegateActivator), Services = [Microsoft.Bot.Builder.Dialogs.Internals.IDialogStack, Microsoft.Bot.Builder.Dialogs.Internals.IDialogTask], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = Shared, Ownership = OwnedByLifetimeScope ---> Object reference not set to an instance of an object. (See inner exception for details.)"

With inner Exception:

"Object reference not set to an instance of an object."

" at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.<Execute>b__5_0()\r\n at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func1 creator)\r\n at Autofac.Core.Resolving.InstanceLookup.Execute()\r\n at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable1 parameters, Object& instance)\r\n at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable1 parameters)\r\n at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable1 parameters)\r\n at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context)\r\n at Progressive.CQBot.Controllers.MessagesController.d__0.MoveNext() in D:\Source\Repos\QUO_Cognitive_Quoting\Src\CQBot\Controllers\MessagesController.cs:line 33"

Is the advice in the linked answer deprecated? Is there some module registration I'm missing? I would appreciate any direction!

like image 607
Sam Hanley Avatar asked Sep 12 '17 20:09

Sam Hanley


People also ask

What is dialog in bot framework?

What is a dialog in Bot framework? Basically dialog is a class, which allows Bot developer to logically separate various areas of Bot functionality and guide conversational flow.

What is waterfall dialog in bot framework C#?

A waterfall dialog (or waterfall) defines a sequence of steps, allowing your bot to guide a user through a linear process. These dialogs are designed to work within the context of a component dialog.

What is dialog context?

From code outside of a dialog in the set, use DialogSet. createContext to create the dialog context. Then use the methods of the dialog context to manage the progression of dialogs in the set. When you implement a dialog, the dialog context is a parameter available to the various methods you override or implement.


1 Answers

The BotData needs to be loaded in scope before resolving the IDialogStack.

Please try the following:

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
    var botData = scope.Resolve<IBotData>();
    await botData.LoadAsync(new System.Threading.CancellationToken());

    var stack = scope.Resolve<IDialogStack>();
}
like image 72
Eric Dahlvang Avatar answered Oct 14 '22 20:10

Eric Dahlvang