c# - 使用 Autofac 在 Microsoft Bot Framework 对话框中注入(inject)外部依赖项

标签 c# autofac botframework

我一直在尝试将服务从 MessagesController 传递给 LuisDialog,如下所示:

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

botService 使用依赖注入(inject)注入(inject)到 MessageController 中。

当我开始机器人对话时出现错误:

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

四处寻找我能找到的解决方案: 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();

但是我找不到详细说明如何将您自己的依赖项注册到现有 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 即可使其正常工作。

问题是 - 注册依赖项并将依赖项注入(inject) 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);

在您的 Controller 中,您可以将主对话框解析为:

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
    await Conversation.SendAsync(activity, () => scope.Resolve<IDialog<object>>());
}

关于c# - 使用 Autofac 在 Microsoft Bot Framework 对话框中注入(inject)外部依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38819193/

相关文章:

c# - 使用 Moq 时出现奇怪的 "Object reference not set to an instance of an object"错误

javascript - 避免在 ASP.NET 中执行嵌入式代码块

c# - 如何使用 autofac 注册两个 WCF 服务契约(Contract)

botframework - 如何从安卓客户端连接到微软机器人框架

c# - 机器人框架: 'State size exceeded configured limit.'

c# - 在 Firebase REST API 上放置 JSON 数据时出现 BadRequest

c# - 既然可以直接返回 Task<T>,为什么还要使用 async 并返回 await?

.net - 如何仅使用 Autofac 注入(inject)一些构造函数参数并结合使用 InjectionModule

c# - Autofac 和 Contract 类

node.js - 异步机器人框架响应可能吗?