mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-05 22:54:12 -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