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 Autofac;
using Kyoo.Models.Exceptions;
@ -42,6 +43,15 @@ namespace Kyoo.Controllers
/// </param>
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>
/// Configure container adding or removing services as the plugins wants.
/// </summary>

View File

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

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using Autofac;
using Autofac.Extras.AttributeMetadata;
@ -6,6 +7,7 @@ using Kyoo.Authentication;
using Kyoo.Controllers;
using Kyoo.Models.Options;
using Kyoo.Postgresql;
using Kyoo.SqLite;
using Kyoo.Tasks;
using Kyoo.TheMovieDb;
using Kyoo.TheTvdb;
@ -23,43 +25,28 @@ namespace Kyoo
/// <summary>
/// The Startup class is used to configure the AspNet's webhost.
/// </summary>
public class Startup
public class PluginsStartup
{
/// <summary>
/// A plugin manager used to load plugins and allow them to configure services / asp net.
/// </summary>
private readonly IPluginManager _plugins;
/// <summary>
/// Created from the DI container, those services are needed to load information and instantiate plugins.s
/// </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 Startup(IWebHostEnvironment hostEnvironment,
IConfiguration configuration,
ILoggerFactory loggerFactory)
/// <param name="plugins">The plugin manager to use to load new plugins and configure the host.</param>
public PluginsStartup(IPluginManager plugins)
{
HostServiceProvider hostProvider = new(hostEnvironment, configuration, loggerFactory);
_plugins = new PluginManager(
hostProvider,
Options.Create(configuration.GetSection(BasicOptions.Path).Get<BasicOptions>()),
loggerFactory.CreateLogger<PluginManager>()
_plugins = plugins;
_plugins.LoadPlugins(
typeof(CoreModule),
typeof(AuthenticationModule),
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>
@ -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>
/// 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.

View File

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