/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services">Specifies the contract for a <see cref="IServiceCollection"/> of service descriptors.</param> /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/> /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/> public void ConfigureServices(IServiceCollection services) { services.AddBot <WelcomeUserBot>(options => { var secretKey = Configuration.GetSection("botFileSecret")?.Value; var botFilePath = Configuration.GetSection("botFilePath")?.Value; if (!File.Exists(botFilePath)) { throw new FileNotFoundException($"The .bot configuration file was not found. botFilePath: {botFilePath}"); } // Loads .bot configuration file and adds a singleton that your Bot can access through dependency injection. var botConfig = BotConfiguration.Load(botFilePath ?? @".\BotConfiguration.bot", secretKey); services.AddSingleton(sp => botConfig ?? throw new InvalidOperationException($"The .bot configuration file could not be loaded. botFilePath: {botFilePath}")); // 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 <WelcomeUserBot>(); // 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."); }; // The Memory Storage used here is for local bot debugging only. When the bot // is restarted, anything stored in memory will be gone. IStorage dataStore = new MemoryStorage(); // For production bots use the Azure Blob or // Azure CosmosDB storage providers. For the Azure // based storage providers, add the Microsoft.Bot.Builder.Azure // Nuget package to your solution. That package is found at: // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/ // Uncomment the following lines to use Azure Blob Storage // //Storage configuration name or ID from the .bot file. // const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>"; // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId); // if (!(blobConfig is BlobStorageService blobStorageConfig)) // { // throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'."); // } // // Default container name. // const string DefaultBotContainer = "<DEFAULT-CONTAINER>"; // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container; // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer); // Create Conversation State object. // The Conversation State object is where we persist anything at the conversation-scope. var userState = new UserState(dataStore); options.State.Add(userState); }); // Create and register state accessors. // Accessors created here are passed into the IBot-derived class on every turn. services.AddSingleton <WelcomeUserStateAccessors>(sp => { var options = sp.GetRequiredService <IOptions <BotFrameworkOptions> >().Value; if (options == null) { throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the State Accessors"); } var userState = options.State.OfType <UserState>().FirstOrDefault(); if (userState == null) { throw new InvalidOperationException("UserState must be defined and added before adding user-scoped state accessors."); } // Create the custom state accessor. // State accessors enable other components to read and write individual properties of state. var accessors = new WelcomeUserStateAccessors(userState) { WelcomeUserState = userState.CreateProperty <WelcomeUserState>(WelcomeUserStateAccessors.WelcomeUserName), }; return(accessors); }); }
/// <summary> /// Initializes a new instance of the <see cref="WelcomeUserBot"/> class. /// </summary> /// <param name="statePropertyAccessor"> Bot state accessor object.</param> public WelcomeUserBot(WelcomeUserStateAccessors statePropertyAccessor, WelcomeUserBotDialogSet dialogSet, BotState botState) { _welcomeUserStateAccessors = statePropertyAccessor ?? throw new System.ArgumentNullException("state accessor can't be null"); _dialogSet = dialogSet ?? throw new ArgumentNullException(nameof(dialogSet)); _botState = botState ?? throw new ArgumentNullException(nameof(botState)); }
/// <summary> /// Initializes a new instance of the <see cref="WelcomeUserBot"/> class. /// </summary> /// <param name="statePropertyAccessor"> Bot state accessor object.</param> public WelcomeUserBot(WelcomeUserStateAccessors statePropertyAccessor) { _welcomeUserStateAccessors = statePropertyAccessor ?? throw new System.ArgumentNullException("state accessor can't be null"); }
/// <summary> /// This method gets called by the runtime. Use this method to add services to the container. /// </summary> /// <param name="services">Specifies the contract for a <see cref="IServiceCollection"/> of service descriptors.</param> /// <seealso cref="https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/dependency-injection"/> /// <seealso cref="https://docs.microsoft.com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0"/> public void ConfigureServices(IServiceCollection services) { // Memory Storage is for local bot debugging only. When the bot // is restarted, everything stored in memory will be gone. IStorage dataStore = new MemoryStorage(); var conversationState = new ConversationState(dataStore); var userState2 = new UserState(dataStore); // For production bots use the Azure Blob or // Azure CosmosDB storage providers. For the Azure // based storage providers, add the Microsoft.Bot.Builder.Azure // Nuget package to your solution. That package is found at: // https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/ // Un-comment the following lines to use Azure Blob Storage // // Storage configuration name or ID from the .bot file. // const string StorageConfigurationId = "<STORAGE-NAME-OR-ID-FROM-BOT-FILE>"; // var blobConfig = botConfig.FindServiceByNameOrId(StorageConfigurationId); // if (!(blobConfig is BlobStorageService blobStorageConfig)) // { // throw new InvalidOperationException($"The .bot file does not contain an blob storage with name '{StorageConfigurationId}'."); // } // // Default container name. // const string DefaultBotContainer = "<DEFAULT-CONTAINER>"; // var storageContainer = string.IsNullOrWhiteSpace(blobStorageConfig.Container) ? DefaultBotContainer : blobStorageConfig.Container; // IStorage dataStore = new Microsoft.Bot.Builder.Azure.AzureBlobStorage(blobStorageConfig.ConnectionString, storageContainer); // Create and add conversation state. //var conversationState = new ConversationState(dataStore); //services.AddSingleton(conversationState); // The dialogset will need a state store accessor. Since the state accessor is only going to be used by the FoodBotDialogSet, use // AddSingleton to register and inline create the FoodBotDialogSet, at the same time creating the the property accessor in the // conversation state //services.AddSingleton(sp => new EchoBotDialogSet(conversationState.CreateProperty<DialogState>("ECHOBOTDIALOGSTATE"))); services.AddBot <WelcomeUserBot>(options => { var appId = Configuration.GetSection("MicrosoftAppId").Value; var appPassword = Configuration.GetSection("MicrosoftAppPassword").Value; options.CredentialProvider = new SimpleCredentialProvider(appId, appPassword); // Catches any errors that occur during a conversation turn and logs them to currently // configured ILogger. ILogger logger = _loggerFactory.CreateLogger <WelcomeUserBot>(); options.OnTurnError = async(context, exception) => { logger.LogError($"Exception caught : {exception}"); await context.SendActivityAsync("Sorry, it looks like something went wrong."); }; // IStorage dataStore2 = new MemoryStorage(); // var userState = new UserState(dataStore2); options.State.Add(userState2); }); // Create and register state accessors. // Accessors created here are passed into the IBot-derived class on every turn. services.AddSingleton <WelcomeUserStateAccessors>(sp => { var options = sp.GetRequiredService <IOptions <BotFrameworkOptions> >().Value; if (options == null) { throw new InvalidOperationException("BotFrameworkOptions must be configured prior to setting up the State Accessors"); } var userState = options.State.OfType <UserState>().FirstOrDefault(); if (userState == null) { throw new InvalidOperationException("UserState must be defined and added before adding user-scoped state accessors."); } // Create the custom state accessor. // State accessors enable other components to read and write individual properties of state. var accessors = new WelcomeUserStateAccessors(userState, conversationState) { WelcomeUserState = userState.CreateProperty <WelcomeUserState>(WelcomeUserStateAccessors.WelcomeUserName), }; return(accessors); }); services.AddSingleton <BotState>(conversationState); // The dialogset will need a state store accessor. Since the state accessor is only going to be used by the FoodBotDialogSet, use // AddSingleton to register and inline create the FoodBotDialogSet, at the same time creating the the property accessor in the // conversation state services.AddSingleton(sp => new WelcomeUserBotDialogSet(conversationState.CreateProperty <DialogState>("WELCOMEBOTDIALOGSTATE2"))); services.AddSingleton <IStatePropertyAccessor <DialogState> >(conversationState.CreateProperty <DialogState>("WELCOMEBOTDIALOGSTATE")); services.AddSingleton <WelcomeUserBotDialogSet>(); }