我一直试图从MessagesController将服务传递给LuisDialog,如下所示:
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
...
await Conversation.SendAsync(activity, () => new ActionDialog(botService));
使用依赖注入将botService注入到MessageController中。
当我开始机器人对话时,我收到错误:
键入&#39; ThetaBot.Services.BotService&#39;在Assembly&#39; ThetaBot.Services,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#39;未标记为可序列化。
寻找解决方案我可以找到: https://github.com/Microsoft/BotBuilder/issues/106
我现在更了解你的问题。我们对服务对象有类似的问题,我们希望从容器而不是序列化的blob中实例化。以下是我们如何在容器中注册这些对象 - 我们在反序列化期间对Key_DoNotSerialize的所有对象应用特殊处理:
builder
.RegisterType<BotToUserQueue>()
.Keyed<IBotToUser>(FiberModule.Key_DoNotSerialize)
.AsSelf()
.As<IBotToUser>()
.SingleInstance();
但是,我找不到详细说明如何在现有Bot Framework模块中注册自己的依赖项的示例或文档。
我还发现https://github.com/Microsoft/BotBuilder/issues/252表示应该可以从容器中实例化对话框。
我尝试过这个建议:
Func<IDialog<object>> makeRoot = () => actionDialog;
await Conversation.SendAsync(activity, makeRoot);
与:
一起builder
.RegisterType<ActionDialog>()
.Keyed<ActionDialog>(FiberModule.Key_DoNotSerialize)
.AsSelf()
.As<ActionDialog>()
.SingleInstance();
这不起作用。
我也尝试过:
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>());
}
与ApplicationModule中的以下内容一起:
builder
.RegisterType<ActionDialog>()
.Keyed<ActionDialog>(FiberModule.Key_DoNotSerialize)
.AsSelf()
.As<ActionDialog>()
.SingleInstance();
这不起作用,我遇到同样的问题。
如果我只是将所有服务及其依赖项标记为可序列化,我可以在不需要使用FiberModule.Key_DoNotSerialize的情况下将其工作。
问题是 - 在Bot框架对话框中注册和注入依赖项的正确/首选/推荐方法是什么?
答案 0 :(得分:10)
在Global.asax.cs中,您可以执行以下操作来注册您的服务/对话框:
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<IntroDialog>()
.As<IDialog<object>>()
.InstancePerDependency();
builder.RegisterType<JobsMapper>()
.Keyed<IMapper<DocumentSearchResult, GenericSearchResult>>(FiberModule.Key_DoNotSerialize)
.AsImplementedInterfaces()
.SingleInstance();
builder.RegisterType<AzureSearchClient>()
.Keyed<ISearchClient>(FiberModule.Key_DoNotSerialize)
.AsImplementedInterfaces()
.SingleInstance();
builder.Update(Conversation.Container);
在控制器中,您可以将主对话框解析为:
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
await Conversation.SendAsync(activity, () => scope.Resolve<IDialog<object>>());
}