简体   繁体   English

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

Since the Microsoft Bot Framework is using Autofac as a dependency, I figured I'd use it in the rest of my project (using the Bot Framework project scaffold ). 由于Microsoft Bot Framework使用Autofac作为依赖项,我想我会在项目的其余部分(使用Bot Framework项目脚手架 )中使用它。 I'm trying to load the correct Bot Framework IDialog using DI. 我正在尝试使用DI加载正确的Bot Framework IDialog My Global.asax.cs looks like this: 我的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);            
}

The ActivityTypes are string constants that equate to message , conversationUpdate , etc. For my controllers, I have a base that looks like this to resolve the Autofac DI Container: ActivityTypes是等同于messageconversationUpdate等的字符串常量。对于我的控制器,我有一个类似于此的基础来解析Autofac DI容器:

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

In my MessagesController that catches all bot interactions, my code looks like this: 在我捕获所有bot交互的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);
    }
}

The activity.GetActivityType() simply returns back a string with equates with the ActivityTypes referred to above. activity.GetActivityType()只返回一个字符串,其等同于上面提到的ActivityTypes When I breakpoint on scope.ResolveNamed , it looks like the correct IDialog has been returned to dialog . 当我在scope.ResolveNamed上断点时,看起来正确的IDialog已经返回到对话框 However, when the Conversation.SendAsync runs, the wrong IDialog is running. 但是,当Conversation.SendAsync运行时,错误的IDialog正在运行。 For example, I see EchoDialogState being injected into dialog , but then the code inside WelcomeDialog1 is always being called instead. 例如,我看到EchoDialogState被注入到对话框中 ,但随后总是调用WelcomeDialog1中的代码。

Am I doing this wrong? 我做错了吗? What would cause the incorrect IDialog being run inside the delegate function? 什么会导致在委托函数中运行不正确的IDialog

If it helps, this is an example of the IDialog that's running: 如果它有帮助,这是正在运行的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);
    }
}

Instead of doing a context.Wait in the MessageReceivedAsync method of your WelcomeDialog1, try doing a context.Done. 而不是在WelcomeDialog1的MessageReceivedAsync方法中执行context.Wait,尝试执行context.Done。

In the way you are doing it now, the WelcomeDialog1 is still listening to your messages. 就像你现在这样做,WelcomeDialog1仍然在听你的消息。 Usually the welcome message is done using the ConnectorClient in the MessageController as it is a simple message. 通常欢迎消息是使用MessageController中的ConnectorClient完成的,因为它是一条简单的消息。 You don't need all the dialog infrastructure. 您不需要所有对话框基础结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM