/// <summary> /// Integrates the given module with the core by replacing other modules, /// configuring routes and setting up wrappers. /// </summary> /// <param name="moduleName">The name of the loaded module as specified in the config</param> /// <param name="module">The loaded module</param> /// <exception cref="NotSupportedException">When duplicate content paths are found</exception> private void Integrate(string moduleName, IModule module) { _log.Info($"Integrating module '{moduleName}'"); if (module is ILogger) { _log = (ILogger)module; _log.Info($"Loaded module '{moduleName}' implements ILogger, replaced Bootstrap logger"); // TODO: Find a better way to reload modules in other modules /// See Issue #3 /// https://github.com/ProjectLimitless/ProjectLimitless/issues/3 _analysis.SetLog(_log); CoreContainer.Instance.IOManager.SetLog(_log); } if (module is IUIModule) { // Multiple UI modules are allowed, we can add all their paths var ui = module as IUIModule; string contentPath = ui.GetContentPath(); if (CoreContainer.Instance.RouteManager.AddContentRoute(contentPath)) { _log.Debug($"Added content path '{contentPath}' for module '{moduleName}'"); } else { _log.Critical($"Previously loaded IUIModule already uses the content path '{contentPath}' specified in '{moduleName}'"); throw new NotSupportedException($"Previously loaded IUIModule already uses the content path '{contentPath}' specified in '{moduleName}'"); } } if (module is IIdentityProvider) { var identityProvider = module as IIdentityProvider; CoreContainer.Instance.RouteManager.AddRoutes(identityProvider.GetRequiredAPIRoutes(_analysis.Record)); CoreContainer.Instance.IdentityProvider = identityProvider; #if DEBUG _log.Debug($"Added {identityProvider.GetRequiredAPIRoutes(_analysis.Record).Count} required API routes for 'IdentityProvider'"); #endif } // Add this provider to the input pipeline if (module is IIOProcessor) { var inputProvider = module as IIOProcessor; try { CoreContainer.Instance.IOManager.RegisterProvider(inputProvider); } catch (NotSupportedException ex) { _log.Error($"Unable to load input provider '{inputProvider.GetType().Name}': {ex.Message}"); } } if (module is IInteractionEngine) { var interactionEngine = module as IInteractionEngine; // TODO: Better replacement. See Issue #3 // https://github.com/ProjectLimitless/ProjectLimitless/issues/3 CoreContainer.Instance.IOManager.SetEngine(interactionEngine); CoreContainer.Instance.RouteManager.AddRoutes(interactionEngine.GetRequiredAPIRoutes(_analysis.Record)); #if DEBUG _log.Debug($"Added {interactionEngine.GetRequiredAPIRoutes(_analysis.Record).Count} required API routes for 'InteractionEngine'"); #endif } // TODO: Add decorating to interfaces with required paths // TODO: Testing hook var moduleRoutes = module.GetAPIRoutes(_analysis.Record); if (CoreContainer.Instance.RouteManager.AddRoutes(moduleRoutes)) { _log.Info($"Added {moduleRoutes.Count} new API routes for module '{moduleName}'"); } else { _log.Warning($"Unable to add all API routes for module '{moduleName}'. Possible duplicate route and method."); } }