Bot Framework-Luis对话框-从Web.config设置LuisModel属性

时间:2018-09-28 14:54:04

标签: c# botframework constants luis

我正在基于LUIS的Microsoft Bot Framework中编写聊天机器人。 (这是我第一次使用LUIS)。我有一个基本的LuisDialog类,我想在其中设置LuisModel属性。 问题是,定义LuisModel需要常量值。我想从Web.config文件中检索这些值。

这失败,并且我收到一条错误消息,提示“属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式”。 (这是因为从Web.config文件中检索了值。)

是否可以从Web.config文件中检索这些值并将其设置在属性中?

我尝试了以下解决方案,但未成功:

[Serializable]
[LuisModel(Constants.LuisModelId, Constants.LuisSubscriptionKey)]
public class LuisDialog : LuisDialog<object>
{
    //...
}

internal static class Constants
{
    internal const string LuisModelId = WebConfigurationManager.AppSettings.Get("LuisModelId");
    internal const string LuisSubscriptionKey = WebConfigurationManager.AppSettings.Get("LuisSubscriptionKey");
}

2 个答案:

答案 0 :(得分:0)

您不能直接在web.config的属性上设置它们,因为属性是在编译时评估的。

但是,您可以做到。 LuisDialog类的构造函数采用ILuisService的参数。

public LuisDialog(params ILuisService[] services)

现在,ILuisService具有一个适当命名的默认实现,即LuisService,它具有采用ILuisModel参数的构造函数

public LuisService(ILuisModel model)

与我同在,我要学习好东西。 ILuisModel的实现在类LuisModelAttribute中。

public class LuisModelAttribute : Attribute, ILuisModel, ILuisOptions, IEquatable<ILuisModel>

在LuisModelAttributes构造函数中,您应该开始了解它的运行方向

public LuisModelAttribute(string modelID, string subscriptionKey,
        LuisApiVersion apiVersion = LuisApiVersion.V2, string domain = null, double threshold = 0.0d)

此构造函数带有modelId和subscriptionKey!这就是您要寻找的。 现在,下一个问题是如何将所有这些放在一起?答案是使用autofac进行依赖注入。

我通常为我的所有DI注册声明一个新的Autofac模型类。

internal sealed class MainModule : Module

我们需要注册的第一件事是LuisModelAttribute的实例

var luisModelAttr = new LuisModelAttribute(ConfigurationManager.AppSettings["luis:AppId"],
    ConfigurationManager.AppSettings["luis:ServiceKey"],
    LuisApiVersion.V2,
    ConfigurationManager.AppSettings["luis:APIHostName"])
{
    BingSpellCheckSubscriptionKey = ConfigurationManager.AppSettings["luis:BingSpellCheckKey"],
    SpellCheck = true
}

这没有注册任何内容,它只是创建了LuisModelAttribute类的实例。现在,注册它。

builder.Register(c => luisModelAttr).AsSelf().AsImplmentedInterface().SingleInstance();

接下来,注册您的Luis对话框,您将需要在构造函数参数中包含ILuisService

builder.Register(c => new MyLuisDialog(c.Resolve<ILuisService>())
    .As<IDialog<IMessageActivity>>()
    .InstancePerDependency();

最后一次注册LuisService,或在我们的示例中为ILuisService

builder.RegisterType<LuisService>()
    .Keyed<ILuisService>(FiberModule.Key_DoNotSerilialize)
    .AsImplementedInterface()
    .SingleInstance();

那么,这里发生了什么?因为LuisModelAttribute实现了ILuisModel,所以Autofac会知道将LuisModelAttribute作为LuisService的参数,并且会知道将实现ILuisService的LuisService包含在我们的luis对话框MyLuisDialog中。

您的具体实现可能有所不同,但是此示例将为您提供所需的信息。祝你好运!

答案 1 :(得分:0)

创建自定义LuisModelAttribute

  public sealed class CustomLuisAttribute : LuisModelAttribute
    {
        public CustomLuisAttribute(string modelID, string subscriptionKey, LuisApiVersion apiVersion = LuisApiVersion.V2, string domain = null, double threshold = 0) 
            : base(modelID : ConfigurationManager.AppSettings["ModelId"], subscriptionKey : ConfigurationManager.AppSettings["LuisSubscriptionKey"])
        {
        }
    }

将其用作根对话框的属性

[CustomLuisAttribute]
[Serializable]
public class RootDialog : LuisDialog<object>
{
}