使用Autofac在Microsoft Bot Framework对话框中注入外部依赖项

本文关键字:注入 外部 依赖 对话框 Framework Autofac Microsoft Bot 使用 | 更新日期: 2023-09-27 18:01:09

我一直试图将服务从MessagesController传递到LuisDialog,如下所示:

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
...
await Conversation.SendAsync(activity, () => new ActionDialog(botService));

使用依赖项注入将botService注入到MessageController中。

当我开始机器人对话时,我会收到一个错误:

程序集"ThetaBot.Services,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"中的类型"ThetaBot.Services.BotService"未标记为可序列化。

四处寻找解决方案,我可以找到: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 Framework对话框中注册和注入依赖项的正确/首选/推荐方式是什么?

使用Autofac在Microsoft Bot Framework对话框中注入外部依赖项

在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>>());
}