Fixing module loading

This commit is contained in:
Zoe Roux 2021-04-30 02:02:11 +02:00
parent 0453e74b67
commit c0f1f80a40
7 changed files with 43 additions and 8 deletions

View File

@ -46,6 +46,12 @@ namespace Kyoo.Controllers
/// put typeof(ILibraryManager). /// put typeof(ILibraryManager).
/// </remarks> /// </remarks>
Type[] Requires { get; } Type[] Requires { get; }
/// <summary>
/// True if this plugin is needed to start Kyoo. If this is true and a dependency could not be met, app startup
/// will be canceled. If this is false, Kyoo's startup will continue without enabling this plugin.
/// </summary>
bool IsRequired { get; }
/// <summary> /// <summary>
/// A configure method that will be run on plugin's startup. /// A configure method that will be run on plugin's startup.

View File

@ -14,7 +14,7 @@ namespace Kyoo.Models.Exceptions
/// <param name="plugin">The name of the plugin that can't be loaded.</param> /// <param name="plugin">The name of the plugin that can't be loaded.</param>
/// <param name="dependency">The name of the missing dependency.</param> /// <param name="dependency">The name of the missing dependency.</param>
public MissingDependencyException(string plugin, string dependency) public MissingDependencyException(string plugin, string dependency)
: base($"No {dependency} are available in kyoo but the plugin {plugin} requires it.") : base($"No {dependency} are available in Kyoo but the plugin {plugin} requires it.")
{} {}
} }
} }

View File

@ -29,6 +29,9 @@ namespace Kyoo.Postgresql
/// <inheritdoc /> /// <inheritdoc />
public Type[] Requires => Array.Empty<Type>(); public Type[] Requires => Array.Empty<Type>();
/// <inheritdoc />
public bool IsRequired => true;
/// <summary> /// <summary>

View File

@ -88,14 +88,17 @@ namespace Kyoo.Controllers
return assembly.GetTypes() return assembly.GetTypes()
.Where(x => typeof(IPlugin).IsAssignableFrom(x)) .Where(x => typeof(IPlugin).IsAssignableFrom(x))
.Where(x => _plugins.All(y => y.GetType() != x)) .Where(x => _plugins.All(y => y.GetType() != x))
.Select(x => (IPlugin)_container.Resolve(x)); .Select(x => (IPlugin)_container.Resolve(x))
.ToArray();
} }
catch (Exception ex) catch (Exception ex)
{ {
_logger.LogError(ex, "Could not load the plugin at {Path}", path); _logger.LogError(ex, "Could not load the plugin at {Path}", path);
return Array.Empty<IPlugin>(); return Array.Empty<IPlugin>();
} }
}).ToArray(); }).ToList();
if (!_plugins.Any())
newPlugins.Add(new CoreModule());
_plugins.AddRange(newPlugins); _plugins.AddRange(newPlugins);
ICollection<Type> available = _plugins.SelectMany(x => x.Provides).ToArray(); ICollection<Type> available = _plugins.SelectMany(x => x.Provides).ToArray();
@ -103,8 +106,14 @@ namespace Kyoo.Controllers
{ {
Type missing = plugin.Requires.FirstOrDefault(x => available.All(y => !y.IsAssignableTo(x))); Type missing = plugin.Requires.FirstOrDefault(x => available.All(y => !y.IsAssignableTo(x)));
if (missing != null) if (missing != null)
throw new MissingDependencyException(plugin.Name, missing.Name); {
plugin.Configure(_container); Exception error = new MissingDependencyException(plugin.Name, missing.Name);
_logger.LogCritical(error, "A plugin's dependency could not be met");
if (plugin.IsRequired)
Environment.Exit(1);
}
else
plugin.Configure(_container);
} }
if (!_plugins.Any()) if (!_plugins.Any())

View File

@ -48,6 +48,9 @@ namespace Kyoo
typeof(DatabaseContext) typeof(DatabaseContext)
}; };
/// <inheritdoc />
public bool IsRequired => true;
/// <inheritdoc /> /// <inheritdoc />
public void Configure(IUnityContainer container) public void Configure(IUnityContainer container)
{ {

View File

@ -49,7 +49,14 @@ namespace Kyoo
IWebHostBuilder host = CreateWebHostBuilder(args); IWebHostBuilder host = CreateWebHostBuilder(args);
if (debug != null) if (debug != null)
host = host.UseEnvironment(debug == true ? "Development" : "Production"); host = host.UseEnvironment(debug == true ? "Development" : "Production");
await host.Build().RunAsync(); try
{
await host.Build().RunAsync();
}
catch (Exception ex)
{
new Logger<Startup>(new LoggerFactory()).LogCritical(ex, "Unhandled exception");
}
} }
/// <summary> /// <summary>
@ -74,7 +81,7 @@ namespace Kyoo
{ {
UnityContainer container = new(); UnityContainer container = new();
container.EnableDebugDiagnostic(); container.EnableDebugDiagnostic();
return new WebHostBuilder() return new WebHostBuilder()
.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory) .UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
.UseConfiguration(SetupConfig(new ConfigurationBuilder(), args).Build()) .UseConfiguration(SetupConfig(new ConfigurationBuilder(), args).Build())

View File

@ -44,6 +44,8 @@ namespace Kyoo
{ {
string publicUrl = _configuration.GetValue<string>("public_url"); string publicUrl = _configuration.GetValue<string>("public_url");
services.AddMvc().AddControllersAsServices();
services.AddSpaStaticFiles(configuration => services.AddSpaStaticFiles(configuration =>
{ {
configuration.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"); configuration.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
@ -141,6 +143,11 @@ namespace Kyoo
AllowedOrigins = { new Uri(publicUrl).GetLeftPart(UriPartial.Authority) } AllowedOrigins = { new Uri(publicUrl).GetLeftPart(UriPartial.Authority) }
}); });
} }
public void ConfigureContainer(IUnityContainer container)
{
// TODO move this to the configure section and figure out a way to reload ControllerActivators with the updated unity container
}
public void Configure(IUnityContainer container, IApplicationBuilder app, IWebHostEnvironment env) public void Configure(IUnityContainer container, IApplicationBuilder app, IWebHostEnvironment env)
{ {
@ -204,7 +211,7 @@ namespace Kyoo
if (env.IsDevelopment()) if (env.IsDevelopment())
spa.UseAngularCliServer("start"); spa.UseAngularCliServer("start");
}); });
container.RegisterType<IPluginManager, PluginManager>(new SingletonLifetimeManager()); container.RegisterType<IPluginManager, PluginManager>(new SingletonLifetimeManager());
IPluginManager pluginManager = new PluginManager(container, _configuration, new Logger<PluginManager>(_loggerFactory)); IPluginManager pluginManager = new PluginManager(container, _configuration, new Logger<PluginManager>(_loggerFactory));
pluginManager.ReloadPlugins(); pluginManager.ReloadPlugins();