Startup: Centering workflow arround the plugin manager

This commit is contained in:
Zoe Roux 2021-08-07 01:30:22 +02:00
parent a64cbcea62
commit 6d1e1261f8
4 changed files with 60 additions and 46 deletions

View File

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using Autofac; using Autofac;
using Kyoo.Models.Exceptions; using Kyoo.Models.Exceptions;
@ -41,6 +42,15 @@ namespace Kyoo.Controllers
/// You should not try to put plugins from the plugins directory here as they will get automatically loaded. /// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
/// </param> /// </param>
public void LoadPlugins(ICollection<IPlugin> plugins); public void LoadPlugins(ICollection<IPlugin> plugins);
/// <summary>
/// Load plugins and their dependencies from the plugin directory.
/// </summary>
/// <param name="plugins">
/// An initial plugin list to use.
/// You should not try to put plugins from the plugins directory here as they will get automatically loaded.
/// </param>
public void LoadPlugins(params Type[] plugins);
/// <summary> /// <summary>
/// Configure container adding or removing services as the plugins wants. /// Configure container adding or removing services as the plugins wants.

View File

@ -135,6 +135,12 @@ namespace Kyoo.Controllers
_logger.LogInformation("Plugin enabled: {Plugins}", _plugins.Select(x => x.Name)); _logger.LogInformation("Plugin enabled: {Plugins}", _plugins.Select(x => x.Name));
} }
/// <inheritdoc />
public void LoadPlugins(params Type[] plugins)
{
throw new NotImplementedException();
}
/// <inheritdoc /> /// <inheritdoc />
public void ConfigureContainer(ContainerBuilder builder) public void ConfigureContainer(ContainerBuilder builder)
{ {

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using Autofac; using Autofac;
using Autofac.Extras.AttributeMetadata; using Autofac.Extras.AttributeMetadata;
@ -6,6 +7,7 @@ using Kyoo.Authentication;
using Kyoo.Controllers; using Kyoo.Controllers;
using Kyoo.Models.Options; using Kyoo.Models.Options;
using Kyoo.Postgresql; using Kyoo.Postgresql;
using Kyoo.SqLite;
using Kyoo.Tasks; using Kyoo.Tasks;
using Kyoo.TheMovieDb; using Kyoo.TheMovieDb;
using Kyoo.TheTvdb; using Kyoo.TheTvdb;
@ -23,43 +25,28 @@ namespace Kyoo
/// <summary> /// <summary>
/// The Startup class is used to configure the AspNet's webhost. /// The Startup class is used to configure the AspNet's webhost.
/// </summary> /// </summary>
public class Startup public class PluginsStartup
{ {
/// <summary> /// <summary>
/// A plugin manager used to load plugins and allow them to configure services / asp net. /// A plugin manager used to load plugins and allow them to configure services / asp net.
/// </summary> /// </summary>
private readonly IPluginManager _plugins; private readonly IPluginManager _plugins;
/// <summary> /// <summary>
/// Created from the DI container, those services are needed to load information and instantiate plugins.s /// Created from the DI container, those services are needed to load information and instantiate plugins.s
/// </summary> /// </summary>
/// <param name="hostEnvironment"> /// <param name="plugins">The plugin manager to use to load new plugins and configure the host.</param>
/// The host environment that could be used by plugins to configure themself. public PluginsStartup(IPluginManager plugins)
/// </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(IWebHostEnvironment hostEnvironment,
IConfiguration configuration,
ILoggerFactory loggerFactory)
{ {
HostServiceProvider hostProvider = new(hostEnvironment, configuration, loggerFactory); _plugins = plugins;
_plugins = new PluginManager( _plugins.LoadPlugins(
hostProvider, typeof(CoreModule),
Options.Create(configuration.GetSection(BasicOptions.Path).Get<BasicOptions>()), typeof(AuthenticationModule),
loggerFactory.CreateLogger<PluginManager>() typeof(PostgresModule),
typeof(SqLiteModule),
typeof(PluginTvdb),
typeof(PluginTmdb)
); );
// 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, hostEnvironment),
// new SqLiteModule(configuration, host),
new AuthenticationModule(configuration, loggerFactory, hostEnvironment),
new PluginTvdb(configuration),
new PluginTmdb(configuration)
});
} }
/// <summary> /// <summary>
@ -142,6 +129,34 @@ namespace Kyoo
}); });
} }
/// <summary>
/// Create a new <see cref="PluginsStartup"/> from a webhost.
/// This is meant to be used from <see cref="WebHostBuilderExtensions.UseStartup"/>.
/// </summary>
/// <param name="host">The context of the web host.</param>
/// <param name="loggingConfiguration">
/// The method used to configure the logger factory used by the plugin manager and plugins during startup.
/// </param>
/// <returns>A new <see cref="PluginsStartup"/>.</returns>
public static PluginsStartup FromWebHost(WebHostBuilderContext host,
Action<HostBuilderContext, ILoggingBuilder> loggingConfiguration)
{
HostBuilderContext genericHost = new(new Dictionary<object, object>())
{
Configuration = host.Configuration,
HostingEnvironment = host.HostingEnvironment
};
ILoggerFactory logger = LoggerFactory.Create(builder => loggingConfiguration(genericHost, builder));
HostServiceProvider hostProvider = new(host.HostingEnvironment, host.Configuration, logger);
PluginManager plugins = new(
hostProvider,
Options.Create(host.Configuration.GetSection(BasicOptions.Path).Get<BasicOptions>()),
logger.CreateLogger<PluginManager>()
);
return new PluginsStartup(plugins);
}
/// <summary> /// <summary>
/// A simple host service provider used to activate plugins instance. /// 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. /// The same services as a generic host are available and an <see cref="ILoggerFactory"/> has been added.

View File

@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Autofac.Extensions.DependencyInjection; using Autofac.Extensions.DependencyInjection;
using Kyoo.Controllers;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -124,26 +125,8 @@ namespace Kyoo
.UseIIS() .UseIIS()
.UseIISIntegration() .UseIISIntegration()
.UseUrls(configuration.GetValue<string>("basics:url")) .UseUrls(configuration.GetValue<string>("basics:url"))
.UseStartup(host => new Startup( .UseStartup(host => PluginsStartup.FromWebHost(host, loggingConfiguration))
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
};
}
} }
} }