将BotState迁移到Azure表存储:没有IDialogContext访问UserData的可能性更大?

时间:2017-11-29 00:25:27

标签: c# azure botframework

我最近使用Microsoft documentation将自定义状态数据从现已弃用的StateClient切换到Azure表存储,按照以下步骤操作:

  • 创建了一个存储空间
  • 已添加到连接字符串
  • 添加到Global.asax.cs中的Autofac注册

这适用于对话框内的context.UserData.SetValue("myKey", "myValue");等所有调用。

但是当我们没有UserData时,似乎没有更多可能直接从Activity对象获取IDialogContext,例如,如果你想使用MessageController中的这些数据

以前,我在做:

var botState = activity.GetStateClient().BotState;
var userData = await botState.GetUserDataAsync(activity.ChannelId, activity.From.Id, token);

这些行动在最新的BotBuilder版本中宣布弃用。任何解决方案都可以做同等的事情吗?

编辑:

添加我的global.asax.cs:

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        GlobalConfiguration.Configuration.Filters.Add(new ExceptionFilter());

        var builder = new ContainerBuilder();

        //register the bot builder module
        builder.RegisterModule(new DialogModule());

        //register project dependencies
        builder.RegisterModule(new BotModule());

        //Http config 
        var config = GlobalConfiguration.Configuration;

        //register controller
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        //create container
        var container = builder.Build();
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);

        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
}

与BotModule相关联:

public class BotModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        base.Load(builder);

        // Scorable pour l'interruption de dialogue
        builder.Register(c => new InterruptScorable(c.Resolve<IDialogTask>())).As<IScorable<IActivity, double>>().InstancePerLifetimeScope();

        // Manage BotData in Sql Datatable
        var store = new TableBotDataStore(ConfigurationHelper.XXXXX, "BotData");
        builder.Register(c => store).Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore).AsSelf().SingleInstance();
        builder.Register(c => new CachingBotDataStore(store, CachingBotDataStoreConsistencyPolicy.ETagBasedConsistency)).As<IBotDataStore<BotData>>().AsSelf().InstancePerLifetimeScope();

        // Logger de conversation
        builder.Register(c => new ActivityLogger(c.Resolve<IBotData>())).As<IActivityLogger>().InstancePerLifetimeScope();

        // Dialogue de base
        builder.RegisterType<RootDialog>().As<IDialog<object>>().InstancePerDependency();
    }
}

1 个答案:

答案 0 :(得分:0)

我已经修改了一些代码,删除了已弃用的 .Build()方法。

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        Conversation.UpdateContainer(builder =>
        {
            builder.RegisterModule(new DialogModule());
            builder.RegisterModule<BotModule>();
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
        });

        GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(Conversation.Container);

        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
}

以这种方式注册模块后,Jason Sowers在此问题上分享的代码应该有所帮助:https://redux.js.org/docs/recipes/WritingTests.html#async-action-creators