我正在基于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");
}
答案 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>
{
}