/// <summary> /// Includes dotNetify in the application request pipeline. /// </summary> /// <param name="appBuilder">Application builder.</param> /// <param name="config">Delegate to provide custom configuration.</param> public static IApplicationBuilder UseDotNetify(this IApplicationBuilder appBuilder, Action <IDotNetifyConfiguration> config = null) { var provider = appBuilder.ApplicationServices; Logger.Init(provider.GetService <ILoggerFactory>()); var vmControllerFactory = provider.GetService <IVMControllerFactory>(); if (vmControllerFactory == null) { throw new InvalidOperationException("Please add the required service by calling 'IServiceCollection.AddDotNetify()' in the application startup."); } var scopedServiceProvider = provider.GetService <IHubServiceProvider>(); // Use ASP.NET Core DI to provide view model instances by default. Func <Type, object[], object> factoryMethod = (type, args) => { try { return(scopedServiceProvider.FactoryMethod?.Invoke(type, args) ?? ActivatorUtilities.CreateInstance(provider, type, args ?? new object[] { })); } catch (Exception ex) { Logger.LogError($"Failed to create instance of '{type}': {ex.Message}"); throw ex; } }; var dotNetifyConfig = new DotNetifyConfiguration(); dotNetifyConfig.SetFactoryMethod(factoryMethod); config?.Invoke(dotNetifyConfig); // Sets how long to keep a view model controller in memory after it hasn't been accessed for a while. if (dotNetifyConfig.VMControllerCacheExpiration.HasValue) { vmControllerFactory.CacheExpiration = dotNetifyConfig.VMControllerCacheExpiration; } // Add middleware to extract headers from incoming requests. if (!_middlewareTypes.Exists(t => t.Item1 == typeof(ExtractHeadersMiddleware))) { // Place the middleware after any forwarding middleware to ensure it forwards unprocessed data. int pos = _middlewareTypes.FindLastIndex(x => typeof(IForwardingMiddleware).IsAssignableFrom(x.Item1)) + 1; _middlewareTypes.Insert(pos, Tuple.Create(typeof(ExtractHeadersMiddleware), new object[] { })); } // Add middleware factories to the hub. var middlewareFactories = provider.GetService <IList <Tuple <Type, Func <IMiddlewarePipeline> > > >(); _middlewareTypes.ForEach(t => middlewareFactories?.Add(Tuple.Create <Type, Func <IMiddlewarePipeline> >(t.Item1, () => (IMiddlewarePipeline)factoryMethod(t.Item1, t.Item2)))); // Add filter factories to the hub. var filterFactories = provider.GetService <IDictionary <Type, Func <IVMFilter> > >(); _filterTypes.ForEach(t => filterFactories?.Add(t.Item1, () => (IVMFilter)factoryMethod(t.Item1, t.Item2))); _useDotNetify = true; return(appBuilder); }