我正在使用Microsoft Bot Framework V4版本的机器人。该文档真的很糟糕,当我尝试存储de UserSate和ConversationState时,我遇到了Cosmos DB(Azure)的问题。
我尝试了Google的所有结果,但没有任何效果。另外,实际上没有太多有关该框架的信息。
下面是文件Startup.cs的代码。
public void ConfigureServices(IServiceCollection services)
{
services.AddBot<SeguritoBot>(options =>
{
var secretKey = Configuration.GetSection("botFileSecret")?.Value;
var botFilePath = Configuration.GetSection("botFilePath")?.Value;
// Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection.
var botConfig = BotConfiguration.Load(botFilePath ?? @".\Segurito.bot", secretKey);
services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot config file could not be loaded. ({botConfig})"));
// Retrieve current endpoint.
var environment = _isProduction ? "production" : "development";
var service = botConfig.Services.FirstOrDefault(s => s.Type == "endpoint" && s.Name == environment);
if (!(service is EndpointService endpointService))
{
throw new InvalidOperationException($"The .bot file does not contain an endpoint with name '{environment}'.");
}
options.CredentialProvider = new SimpleCredentialProvider(endpointService.AppId, endpointService.AppPassword);
// Creates a logger for the application to use.
ILogger logger = _loggerFactory.CreateLogger<SeguritoBot>();
// Catches any errors that occur during a conversation turn and logs them.
options.OnTurnError = async (context, exception) =>
{
logger.LogError($"Exception caught : {exception}");
await context.SendActivityAsync("Sorry, it looks like something went wrong.");
};
var optionsConversation = new CosmosDbStorageOptions()
{
CosmosDBEndpoint = new Uri("--secret--"),
AuthKey = "--secret--",
DatabaseId = "--secret--",
CollectionId = "--secret--"
};
var optionsUser = new CosmosDbStorageOptions()
{
CosmosDBEndpoint = new Uri("--secret--"),
AuthKey = "--secret--",
DatabaseId = "--secret--",
CollectionId = "--secret--"
};
IStorage dataStoreConversationState = new CosmosDbStorage(optionsConversation);
IStorage dataStoreUserState = new CosmosDbStorage(optionsUser);
options.Middleware.Add(new ConversationState<ConversationState>(dataStoreConversationState));
options.Middleware.Add(new UserState<UserState>(dataStoreUserState));
});
}
最后一行显示错误:
The non-generic type 'ConversationState' cannot be used with type arguments
The non-generic type 'ConversationState' cannot be used with type arguments
答案 0 :(得分:0)
好吧,我不确定您从何处获得此代码,但看起来好像来自预发行版本。 ConversationState
和UserState
不再是中间件,也不再是通用的(例如,没有类型实参)。
在4.x发行版上使用CosmosDB进行状态存储时,Startup::ConfigureServices
应该是这样:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Only need a single storage instance unless you really are storing your conversation state and user state in two completely DB instances
var storage = new CosmosDbStorage(new CosmosDbStorageOptions
{
// … set options here …
});
var conversationState = new ConversationState(storage);
var userState = new UserState(storage);
// Add the states as singletons
services.AddSingleton(conversationState);
services.AddSingleton(userState);
// Create state properties accessors and register them as singletons
services.AddSingleton(conversationState.CreateProperty<YourBotConversationState>("MyBotConversationState"));
services.AddSingleton(userState.CreateProperty<YourBotUserState>("MyBotUserState"));
services.AddBot<SeguritoBot>(options =>
{
// … set options here …
});
}
}
现在,在您的机器人中,如果要访问这些属性,可以通过构造函数将它们作为依赖项:
public class SeguritoBot : IBot
{
private readonly ConversationState _conversationState;
private readonly UserState _userState;
private readonly IStatePropertyAccessor<YourBotConversationState> _conversationStatePropertyAccessor;
private readonly IStatePropertyAccessor<YourBotUserState> _userStatePropertyAccessor;
public SeguritoBot(
ConversationState conversationState,
UserState userState,
IStatePropertyAccessor<YourBotConversationState> conversationStatePropertyAccessor,
IStatePropertyAccessor<YourBotUserState> userStatePropertyAccesssor)
{
_conversationState = conversationState;
_userState = userState;
_conversationStatePropertyAcessor = conversationStatePropertyAcessor;
_userStatePropertyAcessor = userStatePropertyAcessor;
}
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
var currentConversationState = await _conversationStatePropertyAccessor.GetAsync(
turnContext,
() => new YourBotConversationState(),
cancellationToken);
// Access properties for this conversation
// currentConversationState.SomeProperty
// Update your conversation state property
await _conversationStatePropertyAccessor.SetAsync(turnContext, currentConversationState, cancellationToken);
// Commit any/all changes to conversation state properties
await _conversationState.SaveChangesAsync(turnContext, cancellationToken);
}
}
很显然,您可以对用户状态属性执行相同的操作,并且可以通过对CreateProperty
进行更多调用并同时注入IStatePropertyAccessor<T>
等来为每个状态范围支持多个属性。