mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-10-26 08:12:35 -04:00 
			
		
		
		
	Host: Using a genric host instead of a web host
This commit is contained in:
		
							parent
							
								
									33b74cac37
								
							
						
					
					
						commit
						a64cbcea62
					
				| @ -2,25 +2,11 @@ using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Threading.Tasks; | ||||
| using JetBrains.Annotations; | ||||
| using Kyoo.Models; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| 
 | ||||
| namespace Kyoo.Controllers | ||||
| { | ||||
| 	/// <summary> | ||||
| 	/// A class wrapping a value that will be set after the completion of the task it is related to. | ||||
| 	/// </summary> | ||||
| 	/// <remarks> | ||||
| 	/// This class replace the use of an out parameter on a task since tasks and out can't be combined. | ||||
| 	/// </remarks> | ||||
| 	/// <typeparam name="T">The type of the value</typeparam> | ||||
| 	public class AsyncRef<T> | ||||
| 	{ | ||||
| 		/// <summary> | ||||
| 		/// The value that will be set before the completion of the task. | ||||
| 		/// </summary> | ||||
| 		public T Value { get; set; } | ||||
| 	} | ||||
| 	 | ||||
| 	/// <summary> | ||||
| 	/// A service to abstract the file system to allow custom file systems (like distant file systems or external providers) | ||||
| 	/// </summary> | ||||
|  | ||||
| @ -55,7 +55,7 @@ namespace Kyoo.Controllers | ||||
| 		/// <returns>A new task parameter.</returns> | ||||
| 		public static TaskParameter Create<T>(string name, string description) | ||||
| 		{ | ||||
| 			return new() | ||||
| 			return new TaskParameter | ||||
| 			{ | ||||
| 				Name = name, | ||||
| 				Description = description, | ||||
| @ -72,7 +72,7 @@ namespace Kyoo.Controllers | ||||
| 		/// <returns>A new task parameter.</returns> | ||||
| 		public static TaskParameter CreateRequired<T>(string name, string description) | ||||
| 		{ | ||||
| 			return new() | ||||
| 			return new TaskParameter | ||||
| 			{ | ||||
| 				Name = name, | ||||
| 				Description = description, | ||||
|  | ||||
							
								
								
									
										17
									
								
								Kyoo.Common/Models/AsyncRef.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Kyoo.Common/Models/AsyncRef.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| namespace Kyoo.Models | ||||
| { | ||||
| 	/// <summary> | ||||
| 	/// A class wrapping a value that will be set after the completion of the task it is related to. | ||||
| 	/// </summary> | ||||
| 	/// <remarks> | ||||
| 	/// This class replace the use of an out parameter on a task since tasks and out can't be combined. | ||||
| 	/// </remarks> | ||||
| 	/// <typeparam name="T">The type of the value</typeparam> | ||||
| 	public class AsyncRef<T> | ||||
| 	{ | ||||
| 		/// <summary> | ||||
| 		/// The value that will be set before the completion of the task. | ||||
| 		/// </summary> | ||||
| 		public T Value { get; set; } | ||||
| 	} | ||||
| } | ||||
| @ -5,6 +5,7 @@ using System.IO; | ||||
| using System.Net.Http; | ||||
| using System.Threading.Tasks; | ||||
| using Kyoo.Common.Models.Attributes; | ||||
| using Kyoo.Models; | ||||
| using Microsoft.AspNetCore.Mvc; | ||||
| 
 | ||||
| namespace Kyoo.Controllers | ||||
|  | ||||
| @ -26,7 +26,7 @@ namespace Kyoo.Controllers | ||||
| 		/// <summary> | ||||
| 		/// The configuration to get the plugin's directory. | ||||
| 		/// </summary> | ||||
| 		private readonly IOptionsMonitor<BasicOptions> _options; | ||||
| 		private readonly IOptions<BasicOptions> _options; | ||||
| 		/// <summary> | ||||
| 		/// The logger used by this class.  | ||||
| 		/// </summary> | ||||
| @ -44,7 +44,7 @@ namespace Kyoo.Controllers | ||||
| 		/// <param name="options">The configuration instance, to get the plugin's directory path.</param> | ||||
| 		/// <param name="logger">The logger used by this class.</param> | ||||
| 		public PluginManager(IServiceProvider provider, | ||||
| 			IOptionsMonitor<BasicOptions> options, | ||||
| 			IOptions<BasicOptions> options, | ||||
| 			ILogger<PluginManager> logger) | ||||
| 		{ | ||||
| 			_provider = provider; | ||||
| @ -106,7 +106,7 @@ namespace Kyoo.Controllers | ||||
| 		/// <inheritdoc /> | ||||
| 		public void LoadPlugins(ICollection<IPlugin> plugins) | ||||
| 		{ | ||||
| 			string pluginFolder = _options.CurrentValue.PluginPath; | ||||
| 			string pluginFolder = _options.Value.PluginPath; | ||||
| 			if (!Directory.Exists(pluginFolder)) | ||||
| 				Directory.CreateDirectory(pluginFolder); | ||||
| 
 | ||||
|  | ||||
| @ -1,13 +1,13 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics.CodeAnalysis; | ||||
| using System.IO; | ||||
| using System.Threading.Tasks; | ||||
| using Autofac; | ||||
| using Autofac.Extensions.DependencyInjection; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.Extensions.Configuration; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.DependencyInjection.Extensions; | ||||
| using Microsoft.Extensions.Hosting; | ||||
| using Microsoft.Extensions.Logging; | ||||
| 
 | ||||
| namespace Kyoo | ||||
| @ -32,7 +32,7 @@ namespace Kyoo | ||||
| 			if (!File.Exists("./settings.json")) | ||||
| 				File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "settings.json"), "settings.json"); | ||||
| 			 | ||||
| 			IWebHostBuilder builder = CreateWebHostBuilder(args); | ||||
| 			IHostBuilder builder = CreateWebHostBuilder(args); | ||||
| 			 | ||||
| 			bool? debug = Environment.GetEnvironmentVariable("ENVIRONMENT")?.ToLowerInvariant() switch | ||||
| 			{ | ||||
| @ -84,24 +84,11 @@ namespace Kyoo | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Create a a web host | ||||
| 		/// Configure the logging. | ||||
| 		/// </summary> | ||||
| 		/// <param name="args">Command line parameters that can be handled by kestrel</param> | ||||
| 		/// <returns>A new web host instance</returns> | ||||
| 		private static IWebHostBuilder CreateWebHostBuilder(string[] args) | ||||
| 		{ | ||||
| 			IConfiguration configuration = SetupConfig(new ConfigurationBuilder(), args).Build(); | ||||
| 
 | ||||
| 			return new WebHostBuilder() | ||||
| 				.ConfigureServices(x => | ||||
| 				{ | ||||
| 					AutofacServiceProviderFactory factory = new(); | ||||
| 					x.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<ContainerBuilder>>(factory)); | ||||
| 				}) | ||||
| 				.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory) | ||||
| 				.UseConfiguration(configuration) | ||||
| 				.ConfigureAppConfiguration(x => SetupConfig(x, args)) | ||||
| 				.ConfigureLogging((context, builder) => | ||||
| 		/// <param name="context">The host context that contains the configuration</param> | ||||
| 		/// <param name="builder">The logger builder to configure.</param> | ||||
| 		private static void _ConfigureLogging(HostBuilderContext context, ILoggingBuilder builder) | ||||
| 		{ | ||||
| 			builder.AddConfiguration(context.Configuration.GetSection("logging")) | ||||
| 				.AddSimpleConsole(x => | ||||
| @ -110,13 +97,53 @@ namespace Kyoo | ||||
| 				}) | ||||
| 				.AddDebug() | ||||
| 				.AddEventSourceLogger(); | ||||
| 				}) | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Create a a web host | ||||
| 		/// </summary> | ||||
| 		/// <param name="args">Command line parameters that can be handled by kestrel</param> | ||||
| 		/// <param name="loggingConfiguration"> | ||||
| 		/// An action to configure the logging. If it is null, <see cref="_ConfigureLogging"/> will be used. | ||||
| 		/// </param> | ||||
| 		/// <returns>A new web host instance</returns> | ||||
| 		public static IHostBuilder CreateWebHostBuilder(string[] args, | ||||
| 			Action<HostBuilderContext, ILoggingBuilder> loggingConfiguration = null) | ||||
| 		{ | ||||
| 			IConfiguration configuration = SetupConfig(new ConfigurationBuilder(), args).Build(); | ||||
| 			loggingConfiguration ??= _ConfigureLogging; | ||||
| 
 | ||||
| 			return new HostBuilder() | ||||
| 				.UseServiceProviderFactory(new AutofacServiceProviderFactory()) | ||||
| 				.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory) | ||||
| 				.ConfigureAppConfiguration(x => SetupConfig(x, args)) | ||||
| 				.ConfigureLogging(loggingConfiguration) | ||||
| 				.ConfigureServices(x => x.AddRouting()) | ||||
| 				.ConfigureWebHost(x => x | ||||
| 					.UseKestrel(options => { options.AddServerHeader = false; }) | ||||
| 					.UseIIS() | ||||
| 					.UseIISIntegration() | ||||
| 					.UseUrls(configuration.GetValue<string>("basics:url")) | ||||
| 				.UseStartup<Startup>(); | ||||
| 					.UseStartup(host => new Startup( | ||||
| 						host.HostingEnvironment,  | ||||
| 						host.Configuration,  | ||||
| 						LoggerFactory.Create(builder => loggingConfiguration(host.ToGenericHost(), builder))) | ||||
| 					) | ||||
| 				); | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Convert an <see cref="WebHostBuilderContext"/> to a <see cref="HostBuilderContext"/>. | ||||
| 		/// </summary> | ||||
| 		/// <param name="host">The <see cref="WebHostBuilderContext"/> to convert.</param> | ||||
| 		/// <returns>A <see cref="HostBuilderContext"/> containing the same properties.</returns> | ||||
| 		private static HostBuilderContext ToGenericHost(this WebHostBuilderContext host) | ||||
| 		{ | ||||
| 			return new HostBuilderContext(new Dictionary<object, object>()) | ||||
| 			{ | ||||
| 				Configuration = host.Configuration, | ||||
| 				HostingEnvironment = host.HostingEnvironment | ||||
| 			}; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -34,31 +34,36 @@ namespace Kyoo | ||||
| 		/// <summary> | ||||
| 		/// Created from the DI container, those services are needed to load information and instantiate plugins.s | ||||
| 		/// </summary> | ||||
| 		/// <param name="hostProvider"> | ||||
| 		/// The ServiceProvider used to create this <see cref="Startup"/> instance. | ||||
| 		/// The host provider that contains only well-known services that are Kyoo independent. | ||||
| 		/// This is used to instantiate plugins that might need a logger, a configuration or an host environment. | ||||
| 		/// <param name="hostEnvironment"> | ||||
| 		/// The host environment that could be used by plugins to configure themself. | ||||
| 		/// </param> | ||||
| 		/// <param name="configuration">The configuration context</param> | ||||
| 		/// <param name="loggerFactory">A logger factory used to create a logger for the plugin manager.</param> | ||||
| 		public Startup(IServiceProvider hostProvider, IConfiguration configuration, ILoggerFactory loggerFactory, IWebHostEnvironment host) | ||||
| 		public Startup(IWebHostEnvironment hostEnvironment,  | ||||
| 			IConfiguration configuration,  | ||||
| 			ILoggerFactory loggerFactory) | ||||
| 		{ | ||||
| 			IOptionsMonitor<BasicOptions> options = hostProvider.GetService<IOptionsMonitor<BasicOptions>>(); | ||||
| 			_plugins = new PluginManager(hostProvider, options, loggerFactory.CreateLogger<PluginManager>()); | ||||
| 			HostServiceProvider hostProvider = new(hostEnvironment, configuration, loggerFactory); | ||||
| 			_plugins = new PluginManager( | ||||
| 				hostProvider,  | ||||
| 				Options.Create(configuration.GetSection(BasicOptions.Path).Get<BasicOptions>()), | ||||
| 				loggerFactory.CreateLogger<PluginManager>() | ||||
| 			); | ||||
| 			 | ||||
| 			// TODO remove postgres from here and load it like a normal plugin. | ||||
| 			// TODO maybe keep all core-plugins here to simplify the build process but use their typeof in the method | ||||
| 			// (to allow simple constructor changes), leaving the instantiation responsibility to the plugin manager. | ||||
| 			_plugins.LoadPlugins(new IPlugin[] { | ||||
| 				new CoreModule(configuration),  | ||||
| 				new PostgresModule(configuration, host), | ||||
| 				new PostgresModule(configuration, hostEnvironment), | ||||
| 				// new SqLiteModule(configuration, host), | ||||
| 				new AuthenticationModule(configuration, loggerFactory, host), | ||||
| 				new AuthenticationModule(configuration, loggerFactory, hostEnvironment), | ||||
| 				new PluginTvdb(configuration), | ||||
| 				new PluginTmdb(configuration) | ||||
| 			}); | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Configure the WebApp services context. | ||||
| 		/// Configure the services context via the <see cref="PluginManager"/>. | ||||
| 		/// </summary> | ||||
| 		/// <param name="services">The service collection to fill.</param> | ||||
| 		public void ConfigureServices(IServiceCollection services) | ||||
| @ -79,6 +84,10 @@ namespace Kyoo | ||||
| 			_plugins.ConfigureServices(services); | ||||
| 		} | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Configure the autofac container via the <see cref="PluginManager"/>. | ||||
| 		/// </summary> | ||||
| 		/// <param name="builder">The builder to configure.</param> | ||||
| 		public void ConfigureContainer(ContainerBuilder builder) | ||||
| 		{ | ||||
| 			builder.RegisterModule<AttributedMetadataModule>(); | ||||
| @ -132,5 +141,57 @@ namespace Kyoo | ||||
| 					spa.UseAngularCliServer("start"); | ||||
| 			}); | ||||
| 		} | ||||
| 		 | ||||
| 		/// <summary> | ||||
| 		/// A simple host service provider used to activate plugins instance. | ||||
| 		/// The same services as a generic host are available and an <see cref="ILoggerFactory"/> has been added. | ||||
| 		/// </summary> | ||||
| 		private class HostServiceProvider : IServiceProvider | ||||
| 		{ | ||||
| 			/// <summary> | ||||
| 			/// The host environment that could be used by plugins to configure themself. | ||||
| 			/// </summary> | ||||
| 			private readonly IWebHostEnvironment _hostEnvironment; | ||||
| 			 | ||||
| 			/// <summary> | ||||
| 			/// The configuration context. | ||||
| 			/// </summary> | ||||
| 			private readonly IConfiguration _configuration; | ||||
| 			 | ||||
| 			/// <summary> | ||||
| 			/// A logger factory used to create a logger for the plugin manager. | ||||
| 			/// </summary> | ||||
| 			private readonly ILoggerFactory _loggerFactory; | ||||
| 
 | ||||
| 			 | ||||
| 			/// <summary> | ||||
| 			/// Create a new <see cref="HostServiceProvider"/> that will return given services when asked. | ||||
| 			/// </summary> | ||||
| 			/// <param name="hostEnvironment"> | ||||
| 			/// The host environment that could be used by plugins to configure themself. | ||||
| 			/// </param> | ||||
| 			/// <param name="configuration">The configuration context</param> | ||||
| 			/// <param name="loggerFactory">A logger factory used to create a logger for the plugin manager.</param> | ||||
| 			public HostServiceProvider(IWebHostEnvironment hostEnvironment, | ||||
| 				IConfiguration configuration, | ||||
| 				ILoggerFactory loggerFactory) | ||||
| 			{ | ||||
| 				_hostEnvironment = hostEnvironment; | ||||
| 				_configuration = configuration; | ||||
| 				_loggerFactory = loggerFactory; | ||||
| 			} | ||||
| 
 | ||||
| 			/// <inheritdoc /> | ||||
| 			public object GetService(Type serviceType) | ||||
| 			{ | ||||
| 				if (serviceType == typeof(IWebHostEnvironment) || serviceType == typeof(IHostEnvironment)) | ||||
| 					return _hostEnvironment; | ||||
| 				if (serviceType == typeof(IConfiguration)) | ||||
| 					return _configuration; | ||||
| 				if (serviceType == typeof(ILoggerFactory)) | ||||
| 					return _loggerFactory; | ||||
| 				return null; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user