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(IEnumerable
1 parameters)\r\n at Autofac.Core.Resolving.InstanceLookup.<Execute>b__5_0()\r\n at Autofac.Core.Lifetime.LifetimeScope.GetOrCreateAndShare(Guid id, Func
1 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, IEnumerable
1 parameters)\r\n at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(IComponentRegistration registration, IEnumerable1 parameters)\r\n at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable
1 parameters, Object& instance)\r\n at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable1 parameters)\r\n at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable
1 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!
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.
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.
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.
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>();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With