Bot Framework Autofac DI - 使用context.Call()时传递依赖关系

时间:2017-08-24 21:57:30

标签: c# autofac botframework

我一直在使用机器人框架,但我只是想知道在使用context.Call()时我对Autofac的使用是否正确。我是否应该将评级服务依赖从RootDialog传递到ReviewDialog(如下所示),还是有更好的方法?

context.Call(new ReviewDialog(_ratingService), ChildDialogHasCompleted);

MessagesController

    [BotAuthentication]
    public class MessagesController : ApiController
    {
        /// <summary>
        /// POST: api/Messages
        /// Receive a message from a user and reply to it
        /// </summary>
        public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
        {
            if (activity.Type == ActivityTypes.Message)
            {
                using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
                {
                    await Conversation.SendAsync(activity, () => scope.Resolve<IDialog<object>>());
                }
            }

            var response = Request.CreateResponse(HttpStatusCode.OK);
            return response;
        }
    }

RootDialog

[Serializable]
public class RootDialog : LuisDialog<object>
{
    private IRatingService _ratingService;

    public RootDialog(IRatingService ratingService)
    {
        this._ratingService = ratingService;
    }

    [LuisIntent("Movie")]
    public async Task IntentSearch(IDialogContext context, LuisResult result)
    {
        // Do stuff

        context.Call(new ReviewDialog(_ratingService), ChildDialogHasCompleted);
    }

    private async Task ChildDialogHasCompleted(IDialogContext context, IAwaitable<object> msg)
    {
        context.Done(true);
    }
}

ReviewDialog

[Serializable]
public class ReviewDialog : IDialog
{
    private IRatingService _ratingService;

    public ReviewDialog(IRatingService ratingService)
    {
        this._ratingService = ratingService;
    }

    public async Task StartAsync(IDialogContext context)
    {
        PromptDialog.Choice(context, ProcessRating, new List<string> { "1", "2", "3", "4", "5" }, "Please select your rating");
    }

    public async Task ProcessRating(IDialogContext context, IAwaitable<string> msg)
    {
        var message = await msg;

        context.UserData.TryGetValue("SelectedMovieId", out int movieId);

        var rating = int.Parse(message);

        _ratingService.Save(movieId, rating);

        await context.PostAsync("Thank you");

        context.Done(true);
    }
}

全局

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configure(WebApiConfig.Register);

        var builder = new ContainerBuilder();

        builder.RegisterType<RootDialog>()
                .As<IDialog<object>>()
                .InstancePerDependency();

        builder.RegisterType<RatingService>()
                .Keyed<IRatingService>(FiberModule.Key_DoNotSerialize)
                .AsImplementedInterfaces();

        builder.Update(Conversation.Container);
    }
}

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

你这样做的方式是完全有效的。要查看其他实施方案,请查看AlarmBot

您这样做的方式通常也是我在对话框中使用DI的方式。还有另一种方法可以使用上下文PrivateConversationDataConversationDataUserData中的数据包在对话框之间传递数据/类,但是你的方式没有任何问题