Autofac 或 Delegates 的工作方式在 ASP.Net Web API Bot Framework 中加载了错误的依赖项

Autofac or the way Delegates work is loading the wrong dependency inside ASP.Net Web API Bot Framework

由于 Microsoft Bot Framework 使用 Autofac 作为依赖项,我想我会在项目的其余部分中使用它(使用 Bot Framework project scaffold)。我正在尝试使用 DI 加载正确的 Bot Framework IDialog。我的 Global.asax.cs 看起来像这样:

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);

    var builder = new ContainerBuilder();            

    // Get your HttpConfiguration.
    var config = GlobalConfiguration.Configuration;

    // Register your Web API controllers.
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // OPTIONAL: Register the Autofac filter provider.
    builder.RegisterWebApiFilterProvider(config);

    builder.RegisterType<EchoDialogState>().Named<IDialog<object>>(ActivityTypes.Message);
    builder.RegisterType<WelcomeDialog1>().Named<IDialog<object>>(ActivityTypes.ConversationUpdate);
    builder.RegisterType<UnknownDialog>().Named<IDialog<object>>(string.Empty).PreserveExistingDefaults();

    // Set the dependency resolver to be Autofac.
    var container = builder.Build();
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);            
}

ActivityTypes 是字符串常量,等同于 messageconversationUpdate 等。对于我的控制器,我有一个看起来像这样的基础来解析 Autofac DI 容器:

public class BaseApiController : ApiController
{
    public IContainer Container { get; private set; } = ((IContainer)((AutofacWebApiDependencyResolver)GlobalConfiguration.Configuration.DependencyResolver).Container);
}

在捕获所有机器人交互的 MessagesController 中,我的代码如下所示:

[BotAuthentication]
public class MessagesController : BaseApiController
{

    public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
    {
        using (var scope = Container.BeginLifetimeScope())
        {
            var dialog = scope.ResolveNamed<IDialog<object>>(activity.GetActivityType());

            await Conversation.SendAsync(activity, () => dialog);
        }

        return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
    }
}

activity.GetActivityType() 简单地 returns 返回一个与上面提到的 ActivityTypes 等同的字符串.当我在 scope.ResolveNamed 上设置断点时,看起来正确的 IDialog 已返回到 dialog.但是,当Conversation.SendAsync运行s时,错误的IDialog是运行ning。例如,我看到 EchoDialogState 被注入到 dialog,但是 WelcomeDialog1 中的代码总是被取而代之的是。

我做错了吗?什么会导致委托函数内的 IDialog 不正确 运行?

如果有帮助,这是 运行ning:

的 IDialog 示例
[Serializable]
public class WelcomeDialog1 : IDialog<object>
{
    public async Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);
    }
    public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
    {
        var message = await argument;
        var name = message.From.Name;

        await context.PostAsync($"Hi {name}. Welcome to SMEBot! First time here stuff.");
        context.Wait(MessageReceivedAsync);
    }
}

不要在 WelcomeDialog1 的 MessageReceivedAsync 方法中执行 context.Wait,而是尝试执行 context.Done。

按照您现在的方式,WelcomeDialog1 仍在收听您的消息。通常欢迎消息是使用 MessageController 中的 ConnectorClient 完成的,因为它是一条简单的消息。您不需要所有对话基础设施。