使用Autofac在Microsoft Bot Framework对话框中注入外部依赖项 [英] Injecting external dependencies in Microsoft Bot Framework Dialog using Autofac

查看:106
本文介绍了使用Autofac在Microsoft Bot Framework对话框中注入外部依赖项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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));

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

The botService is injected into the MessageController using dependency injection.

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

When I start a bot conversation I get an error:

在程序集"ThetaBot.Services,版本= 1.0.0.0,文化=中性,PublicKeyToken =空"中,类型"ThetaBot.Services.BotService"未标记为可序列化.

Type 'ThetaBot.Services.BotService' in Assembly 'ThetaBot.Services, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

四处寻找解决方案,我可以找到: https://github.com/Microsoft/BotBuilder/issues/106

Looking around for a solution I can find: https://github.com/Microsoft/BotBuilder/issues/106

我现在更好地理解了你的问题.我们想要从容器而不是从序列化的Blob实例化服务对象,这也存在类似的问题.这是我们在容器中注册这些对象的方式-我们在反序列化期间对所有具有Key_DoNotSerialize键的对象进行特殊处理:

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模块中.

However I cannot find an example or documentation that details how to register your own dependencies into the existing Bot Framework modules.

我还找到了 https://github.com/Microsoft/BotBuilder/issues/252表示应该可以从容器实例化对话框.

I also found https://github.com/Microsoft/BotBuilder/issues/252 which indicates that it should be possible to instantiate the dialogs from the container.

我尝试了这个建议:

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中的以下内容:

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.

如果我只是将所有服务及其依赖项标记为可序列化的,则无需使用FiberModule.Key_DoNotSerialize即可使其正常运行.

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.

问题是-在Bot Framework对话框中注册和注入依赖项的正确/首选/推荐方法是什么?

The question is - what is the correct / preferred / recommended way to register and inject dependencies into Bot Framework Dialogs?

推荐答案

在Global.asax.cs中,您可以执行以下操作来注册服务/对话框:

In the Global.asax.cs, you can do do the following to register your services/dialogs:

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);

然后,在您的控制器中,您可以将主对话框解析为:

In your controller, you can then resolve your main dialog as:

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

这篇关于使用Autofac在Microsoft Bot Framework对话框中注入外部依赖项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆