I've been trying to pass a service to a LuisDialog from the MessagesController like so:
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
...
await Conversation.SendAsync(activity, () => new ActionDialog(botService));
The botService is injected into the MessageController using dependency injection.
When I start a bot conversation I get an error:
Type 'ThetaBot.Services.BotService' in Assembly 'ThetaBot.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
Looking around for a solution I can find: https://github.com/Microsoft/BotBuilder/issues/106
I understand your question better now. We have a similar issue with service objects that we want to instantiate from the container rather than from the serialized blob. Here is how we register those objects in the container - we apply special handling during deserialiation for all objects with the key Key_DoNotSerialize:
builder
.RegisterType<BotToUserQueue>()
.Keyed<IBotToUser>(FiberModule.Key_DoNotSerialize)
.AsSelf()
.As<IBotToUser>()
.SingleInstance();
However I cannot find an example or documentation that details how to register your own dependencies into the existing Bot Framework modules.
I also found https://github.com/Microsoft/BotBuilder/issues/252 which indicates that it should be possible to instantiate the dialogs from the container.
I have tried this suggestion:
Func<IDialog<object>> makeRoot = () => actionDialog;
await Conversation.SendAsync(activity, makeRoot);
Together with:
builder
.RegisterType<ActionDialog>()
.Keyed<ActionDialog>(FiberModule.Key_DoNotSerialize)
.AsSelf()
.As<ActionDialog>()
.SingleInstance();
This does not work.
I have also tried:
var builder = new ContainerBuilder();
builder.RegisterModule(new DialogModule_MakeRoot());
// My application module
builder.RegisterModule(new ApplicationModule());
using (var container = builder.Build())
using (var scope = DialogModule.BeginLifetimeScope(container, activity))
{
await Conversation.SendAsync(activity, () => scope.Resolve<ActionDialog>());
}
Together with the following in the ApplicationModule:
builder
.RegisterType<ActionDialog>()
.Keyed<ActionDialog>(FiberModule.Key_DoNotSerialize)
.AsSelf()
.As<ActionDialog>()
.SingleInstance();
This does not work and I encounter the same issue.
If I simply mark all the services and their dependencies as serializable I can get this to work without the need to use FiberModule.Key_DoNotSerialize.
The question is - what is the correct / preferred / recommended way to register and inject dependencies into Bot Framework Dialogs?