/// <summary> /// Process the intent based on the intent context /// </summary> /// <param name="turnContext">turn context</param> /// <param name="intentContext">intent context</param> /// <param name="cancellationToken"></param> /// <returns>task</returns> public Task ProcessIntentAsync( ITurnContext turnContext, IntentContext intentContext, CancellationToken cancellationToken) { if (!(intentContext is T)) { throw new InvalidOperationException($"intentContext of {intentContext.GetType().Name} is not allowed"); } return(this.ProcessIntentInternalAsync(turnContext, intentContext as T, cancellationToken)); }
/// <summary> /// Get handler type for the given intent context. /// Uses local cache first to avoid unnecessary reflection. /// </summary> /// <param name="intentContext"></param> /// <returns></returns> private Type GetHandlerType(IntentContext intentContext) { var intentContextType = intentContext.GetType(); var result = this.HandlerTypeMap.GetOrAdd( intentContextType, x => { // Not in the map before. Use reflection to get it. var handlerGenericType = typeof(IntentHandler <>); var handlerType = handlerGenericType.MakeGenericType(intentContextType); return(handlerType); }); return(result); }
/// <summary> /// Get the intent handler given the intent context /// </summary> /// <param name="intentContext">intent context</param> /// <returns>task</returns> public IIntentHandler GetIntentHandler(IntentContext intentContext) { intentContext = intentContext ?? throw new ArgumentNullException(nameof(intentContext)); // NOTE - we use service provider and reflection to dynamically locate the intent handler - which can be scoped or transient // and depend on other scoped/transient services. // We cannot direclty resolve them since intents are singletons. var handlerType = this.GetHandlerType(intentContext); var handler = (IIntentHandler)this.serviceProvider.GetService(handlerType); if (handler == null) { var error = $"No handler registered for {intentContext.GetType().Name}."; this.logger.LogError(error); throw new InvalidOperationException(error); } return(handler); }