diff --git a/Kyoo.Authentication/AuthenticationModule.cs b/Kyoo.Authentication/AuthenticationModule.cs
index 8e3ea475..085fc2dd 100644
--- a/Kyoo.Authentication/AuthenticationModule.cs
+++ b/Kyoo.Authentication/AuthenticationModule.cs
@@ -9,7 +9,6 @@ using IdentityServer4.Services;
using Kyoo.Authentication.Models;
using Kyoo.Authentication.Views;
using Kyoo.Controllers;
-using Kyoo.Models.Attributes;
using Kyoo.Models.Permissions;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@@ -38,6 +37,12 @@ namespace Kyoo.Authentication
///
public string Description => "Enable OpenID authentication for Kyoo.";
+ ///
+ public Dictionary Configuration => new()
+ {
+ { AuthenticationOption.Path, typeof(AuthenticationOption) }
+ };
+
///
/// The configuration to use.
@@ -53,11 +58,6 @@ namespace Kyoo.Authentication
/// The environment information to check if the app runs in debug mode
///
private readonly IWebHostEnvironment _environment;
-
- ///
- /// The configuration manager used to register typed/untyped implementations.
- ///
- [Injected] public IConfigurationManager ConfigurationManager { private get; set; }
///
@@ -88,10 +88,6 @@ namespace Kyoo.Authentication
// TODO handle direct-videos with bearers (probably add a cookie and a app.Use to translate that for videos)
// TODO Check if tokens should be stored.
-
- services.Configure(_configuration.GetSection(PermissionOption.Path));
- services.Configure(_configuration.GetSection(CertificateOption.Path));
- services.Configure(_configuration.GetSection(AuthenticationOption.Path));
List clients = new();
_configuration.GetSection("authentication:clients").Bind(clients);
@@ -129,37 +125,43 @@ namespace Kyoo.Authentication
}
///
- public void ConfigureAspNet(IApplicationBuilder app)
+ public IEnumerable ConfigureSteps => new IStartupAction[]
{
- ConfigurationManager.AddTyped(AuthenticationOption.Path);
-
- app.UseCookiePolicy(new CookiePolicyOptions
+ SA.New(app =>
{
- MinimumSameSitePolicy = SameSiteMode.Strict
- });
- app.UseAuthentication();
- app.Use((ctx, next) =>
+ PhysicalFileProvider provider = new(Path.Combine(
+ Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
+ "login"));
+ app.UseDefaultFiles(new DefaultFilesOptions
+ {
+ RequestPath = new PathString("/login"),
+ FileProvider = provider,
+ RedirectToAppendTrailingSlash = true
+ });
+ app.UseStaticFiles(new StaticFileOptions
+ {
+ RequestPath = new PathString("/login"),
+ FileProvider = provider
+ });
+ }, SA.StaticFiles),
+ SA.New(app =>
{
- ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl());
- return next();
- });
- app.UseIdentityServer();
- app.UseAuthorization();
-
- PhysicalFileProvider provider = new(Path.Combine(
- Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
- "login"));
- app.UseDefaultFiles(new DefaultFilesOptions
+ app.UseCookiePolicy(new CookiePolicyOptions
+ {
+ MinimumSameSitePolicy = SameSiteMode.Strict
+ });
+ app.UseAuthentication();
+ }, SA.Authentication),
+ SA.New(app =>
{
- RequestPath = new PathString("/login"),
- FileProvider = provider,
- RedirectToAppendTrailingSlash = true
- });
- app.UseStaticFiles(new StaticFileOptions
- {
- RequestPath = new PathString("/login"),
- FileProvider = provider
- });
- }
+ app.Use((ctx, next) =>
+ {
+ ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl());
+ return next();
+ });
+ app.UseIdentityServer();
+ }, SA.Endpoint),
+ SA.New(app => app.UseAuthorization(), SA.Authorization)
+ };
}
}
\ No newline at end of file
diff --git a/Kyoo.Common/Controllers/IPlugin.cs b/Kyoo.Common/Controllers/IPlugin.cs
index 06670ff3..817435f1 100644
--- a/Kyoo.Common/Controllers/IPlugin.cs
+++ b/Kyoo.Common/Controllers/IPlugin.cs
@@ -1,7 +1,7 @@
using System;
+using System.Collections.Generic;
using Autofac;
using JetBrains.Annotations;
-using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace Kyoo.Controllers
@@ -41,8 +41,26 @@ namespace Kyoo.Controllers
/// By default, a plugin is always enabled. This method can be overriden to change this behavior.
///
virtual bool Enabled => true;
+
+ ///
+ /// A list of types that will be available via the IOptions interfaces and will be listed inside
+ /// an IConfiguration. If a field should be loosely typed, or null
+ /// can be specified.
+ ///
+ ///
+ /// All use of the configuration must be specified here and not registered elsewhere, if a type is registered
+ /// elsewhere the configuration won't be editable via the and all values
+ /// will be discarded on edit.
+ ///
+ Dictionary Configuration { get; }
///
+ /// An optional configuration step to allow a plugin to change asp net configurations.
+ ///
+ ///
+ virtual IEnumerable ConfigureSteps => ArraySegment.Empty;
+
+ ///
/// A configure method that will be run on plugin's startup.
///
/// The autofac service container to register services.
@@ -61,20 +79,6 @@ namespace Kyoo.Controllers
{
// Skipped
}
-
-
- ///
- /// An optional configuration step to allow a plugin to change asp net configurations.
- /// WARNING: This is only called on Kyoo's startup so you must restart the app to apply this changes.
- ///
- ///
- /// The Asp.Net application builder. On most case it is not needed but you can use it to
- /// add asp net functionalities.
- ///
- void ConfigureAspNet(IApplicationBuilder app)
- {
- // Skipped
- }
///
/// An optional function to execute and initialize your plugin.
diff --git a/Kyoo.Common/Controllers/IPluginManager.cs b/Kyoo.Common/Controllers/IPluginManager.cs
index de439cc2..294aabb2 100644
--- a/Kyoo.Common/Controllers/IPluginManager.cs
+++ b/Kyoo.Common/Controllers/IPluginManager.cs
@@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using Autofac;
using Kyoo.Models.Exceptions;
-using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
namespace Kyoo.Controllers
@@ -63,11 +62,5 @@ namespace Kyoo.Controllers
///
/// The service collection to populate
public void ConfigureServices(IServiceCollection services);
-
- ///
- /// Configure an asp net application applying plugins policies.
- ///
- /// The asp net application to configure
- public void ConfigureAspnet(IApplicationBuilder app);
}
}
\ No newline at end of file
diff --git a/Kyoo.Common/Controllers/ITask.cs b/Kyoo.Common/Controllers/ITask.cs
index 4d764fc7..0810b6bf 100644
--- a/Kyoo.Common/Controllers/ITask.cs
+++ b/Kyoo.Common/Controllers/ITask.cs
@@ -5,7 +5,6 @@ using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Kyoo.Models;
-using Kyoo.Models.Attributes;
using Kyoo.Models.Exceptions;
namespace Kyoo.Controllers
@@ -182,11 +181,6 @@ namespace Kyoo.Controllers
/// A token to request the task's cancellation.
/// If this task is not cancelled quickly, it might be killed by the runner.
///
- ///
- /// Your task can have any service as a public field and use the ,
- /// they will be set to an available service from the service container before calling this method.
- /// They also will be removed after this method return (or throw) to prevent dangling services.
- ///
///
/// An exception meaning that the task has failed for handled reasons like invalid arguments,
/// invalid environment, missing plugins or failures not related to a default in the code.
diff --git a/Kyoo.Common/Controllers/StartupAction.cs b/Kyoo.Common/Controllers/StartupAction.cs
new file mode 100644
index 00000000..3d9891a0
--- /dev/null
+++ b/Kyoo.Common/Controllers/StartupAction.cs
@@ -0,0 +1,221 @@
+using System;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Kyoo.Controllers
+{
+ ///
+ /// A list of constant priorities used for 's .
+ /// It also contains helper methods for creating new .
+ ///
+ public static class SA
+ {
+ public const int Before = 5000;
+ public const int Routing = 4000;
+ public const int StaticFiles = 3000;
+ public const int Authentication = 2000;
+ public const int Authorization = 1000;
+ public const int Endpoint = 0;
+ public const int After = -1000;
+
+ ///
+ /// Create a new .
+ ///
+ /// The action to run
+ /// The priority of the new action
+ /// A new
+ public static StartupAction New(Action action, int priority)
+ => new(action, priority);
+
+ ///
+ /// Create a new .
+ ///
+ /// The action to run
+ /// The priority of the new action
+ /// A dependency that this action will use.
+ /// A new
+ public static StartupAction New(Action action, int priority)
+ => new(action, priority);
+
+ ///
+ /// Create a new .
+ ///
+ /// The action to run
+ /// The priority of the new action
+ /// A dependency that this action will use.
+ /// A second dependency that this action will use.
+ /// A new
+ public static StartupAction New(Action action, int priority)
+ => new(action, priority);
+
+ ///
+ /// Create a new .
+ ///
+ /// The action to run
+ /// The priority of the new action
+ /// A dependency that this action will use.
+ /// A second dependency that this action will use.
+ /// A third dependency that this action will use.
+ /// A new
+ public static StartupAction New(Action action, int priority)
+ => new(action, priority);
+ }
+
+
+ ///
+ /// An action executed on kyoo's startup to initialize the asp-net container.
+ ///
+ ///
+ /// This is the base interface, see for a simpler use of this.
+ ///
+ public interface IStartupAction
+ {
+ ///
+ /// The priority of this action. The actions will be executed on descending priority order.
+ /// If two actions have the same priority, their order is undefined.
+ ///
+ int Priority { get; }
+
+ ///
+ /// Run this action to configure the container, a service provider containing all services can be used.
+ ///
+ /// The service provider containing all services can be used.
+ void Run(IServiceProvider provider);
+ }
+
+ ///
+ /// A with no dependencies.
+ ///
+ public class StartupAction : IStartupAction
+ {
+ ///
+ /// The action to execute at startup.
+ ///
+ private readonly Action _action;
+
+ ///
+ public int Priority { get; }
+
+ ///
+ /// Create a new .
+ ///
+ /// The action to execute on startup.
+ /// The priority of this action (see ).
+ public StartupAction(Action action, int priority)
+ {
+ _action = action;
+ Priority = priority;
+ }
+
+ ///
+ public void Run(IServiceProvider provider)
+ {
+ _action.Invoke();
+ }
+ }
+
+ ///
+ /// A with one dependencies.
+ ///
+ /// The dependency to use.
+ public class StartupAction : IStartupAction
+ {
+ ///
+ /// The action to execute at startup.
+ ///
+ private readonly Action _action;
+
+ ///
+ public int Priority { get; }
+
+ ///
+ /// Create a new .
+ ///
+ /// The action to execute on startup.
+ /// The priority of this action (see ).
+ public StartupAction(Action action, int priority)
+ {
+ _action = action;
+ Priority = priority;
+ }
+
+ ///
+ public void Run(IServiceProvider provider)
+ {
+ _action.Invoke(provider.GetRequiredService());
+ }
+ }
+
+ ///
+ /// A with two dependencies.
+ ///
+ /// The dependency to use.
+ /// The second dependency to use.
+ public class StartupAction : IStartupAction
+ {
+ ///
+ /// The action to execute at startup.
+ ///
+ private readonly Action _action;
+
+ ///
+ public int Priority { get; }
+
+ ///
+ /// Create a new .
+ ///
+ /// The action to execute on startup.
+ /// The priority of this action (see ).
+ public StartupAction(Action action, int priority)
+ {
+ _action = action;
+ Priority = priority;
+ }
+
+ ///
+ public void Run(IServiceProvider provider)
+ {
+ _action.Invoke(
+ provider.GetRequiredService(),
+ provider.GetRequiredService()
+ );
+ }
+ }
+
+ ///
+ /// A with three dependencies.
+ ///
+ /// The dependency to use.
+ /// The second dependency to use.
+ /// The third dependency to use.
+ public class StartupAction : IStartupAction
+ {
+ ///
+ /// The action to execute at startup.
+ ///
+ private readonly Action _action;
+
+ ///
+ public int Priority { get; }
+
+ ///
+ /// Create a new .
+ ///
+ /// The action to execute on startup.
+ /// The priority of this action (see ).
+ public StartupAction(Action action, int priority)
+ {
+ _action = action;
+ Priority = priority;
+ }
+
+ ///
+ public void Run(IServiceProvider provider)
+ {
+ _action.Invoke(
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService()
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/Kyoo.Common/Models/Attributes/InjectedAttribute.cs b/Kyoo.Common/Models/Attributes/InjectedAttribute.cs
deleted file mode 100644
index d517300f..00000000
--- a/Kyoo.Common/Models/Attributes/InjectedAttribute.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using System;
-using JetBrains.Annotations;
-using Kyoo.Controllers;
-
-namespace Kyoo.Models.Attributes
-{
- ///
- /// An attribute to inform that the service will be injected automatically by a service provider.
- ///
- ///
- /// It should only be used on and it will be injected before
- /// calling .
- ///
- [AttributeUsage(AttributeTargets.Property)]
- [MeansImplicitUse(ImplicitUseKindFlags.Assign)]
- public class InjectedAttribute : Attribute { }
-}
\ No newline at end of file
diff --git a/Kyoo.Postgresql/PostgresModule.cs b/Kyoo.Postgresql/PostgresModule.cs
index bbebf946..372d3e86 100644
--- a/Kyoo.Postgresql/PostgresModule.cs
+++ b/Kyoo.Postgresql/PostgresModule.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Kyoo.Controllers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
@@ -22,6 +23,9 @@ namespace Kyoo.Postgresql
///
public string Description => "A database context for postgresql.";
+
+ ///
+ public Dictionary Configuration => new();
///
public bool Enabled => _configuration.GetSelectedDatabase() == "postgres";
diff --git a/Kyoo.SqLite/SqLiteModule.cs b/Kyoo.SqLite/SqLiteModule.cs
index 45dca0f2..e1c05632 100644
--- a/Kyoo.SqLite/SqLiteModule.cs
+++ b/Kyoo.SqLite/SqLiteModule.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using Kyoo.Controllers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
@@ -22,6 +23,9 @@ namespace Kyoo.SqLite
///
public string Description => "A database context for sqlite.";
+ ///
+ public Dictionary Configuration => new();
+
///
public bool Enabled => _configuration.GetSelectedDatabase() == "sqlite";
diff --git a/Kyoo.TheMovieDb/PluginTmdb.cs b/Kyoo.TheMovieDb/PluginTmdb.cs
index c1d6d494..21990d3c 100644
--- a/Kyoo.TheMovieDb/PluginTmdb.cs
+++ b/Kyoo.TheMovieDb/PluginTmdb.cs
@@ -1,10 +1,8 @@
+using System;
+using System.Collections.Generic;
using Autofac;
using Kyoo.Controllers;
-using Kyoo.Models.Attributes;
using Kyoo.TheMovieDb.Models;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
namespace Kyoo.TheMovieDb
{
@@ -21,45 +19,17 @@ namespace Kyoo.TheMovieDb
///
public string Description => "A metadata provider for TheMovieDB.";
-
-
- ///
- /// The configuration to use.
- ///
- private readonly IConfiguration _configuration;
- ///
- /// The configuration manager used to register typed/untyped implementations.
- ///
- [Injected] public IConfigurationManager ConfigurationManager { private get; set; }
-
-
- ///
- /// Create a new tmdb module instance and use the given configuration.
- ///
- /// The configuration to use
- public PluginTmdb(IConfiguration configuration)
+ ///
+ public Dictionary Configuration => new()
{
- _configuration = configuration;
- }
-
-
+ { TheMovieDbOptions.Path, typeof(TheMovieDbOptions) }
+ };
+
///
public void Configure(ContainerBuilder builder)
{
builder.RegisterProvider();
}
-
- ///
- public void Configure(IServiceCollection services)
- {
- services.Configure(_configuration.GetSection(TheMovieDbOptions.Path));
- }
-
- ///
- public void ConfigureAspNet(IApplicationBuilder app)
- {
- ConfigurationManager.AddTyped(TheMovieDbOptions.Path);
- }
}
}
\ No newline at end of file
diff --git a/Kyoo.TheTvdb/PluginTvdb.cs b/Kyoo.TheTvdb/PluginTvdb.cs
index 74f9483d..2b598807 100644
--- a/Kyoo.TheTvdb/PluginTvdb.cs
+++ b/Kyoo.TheTvdb/PluginTvdb.cs
@@ -1,10 +1,8 @@
+using System;
+using System.Collections.Generic;
using Autofac;
using Kyoo.Controllers;
-using Kyoo.Models.Attributes;
using Kyoo.TheTvdb.Models;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
using TvDbSharper;
namespace Kyoo.TheTvdb
@@ -23,44 +21,17 @@ namespace Kyoo.TheTvdb
///
public string Description => "A metadata provider for The TVDB.";
- ///
- /// The configuration to use.
- ///
- private readonly IConfiguration _configuration;
-
- ///
- /// The configuration manager used to register typed/untyped implementations.
- ///
- [Injected] public IConfigurationManager ConfigurationManager { private get; set; }
-
-
- ///
- /// Create a new tvdb module instance and use the given configuration.
- ///
- /// The configuration to use
- public PluginTvdb(IConfiguration configuration)
+ ///
+ public Dictionary Configuration => new()
{
- _configuration = configuration;
- }
-
-
+ { TvdbOption.Path, typeof(TvdbOption) }
+ };
+
///
public void Configure(ContainerBuilder builder)
{
builder.RegisterType().As();
builder.RegisterProvider();
}
-
- ///
- public void Configure(IServiceCollection services)
- {
- services.Configure(_configuration.GetSection(TvdbOption.Path));
- }
-
- ///
- public void ConfigureAspNet(IApplicationBuilder app)
- {
- ConfigurationManager.AddTyped(TvdbOption.Path);
- }
}
}
\ No newline at end of file
diff --git a/Kyoo/Controllers/PluginManager.cs b/Kyoo/Controllers/PluginManager.cs
index f4d91b81..04dacccc 100644
--- a/Kyoo/Controllers/PluginManager.cs
+++ b/Kyoo/Controllers/PluginManager.cs
@@ -6,7 +6,6 @@ using System.Reflection;
using System.Runtime.Loader;
using Autofac;
using Kyoo.Models.Options;
-using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -148,18 +147,6 @@ namespace Kyoo.Controllers
plugin.Configure(services);
}
- ///
- public void ConfigureAspnet(IApplicationBuilder app)
- {
- foreach (IPlugin plugin in _plugins)
- {
- using IServiceScope scope = _provider.CreateScope();
- Helper.InjectServices(plugin, x => scope.ServiceProvider.GetRequiredService(x));
- plugin.ConfigureAspNet(app);
- Helper.InjectServices(plugin, _ => null);
- }
- }
-
///
/// A custom to load plugin's dependency if they are on the same folder.
///
diff --git a/Kyoo/CoreModule.cs b/Kyoo/CoreModule.cs
index 5fe9e977..6c049aee 100644
--- a/Kyoo/CoreModule.cs
+++ b/Kyoo/CoreModule.cs
@@ -1,10 +1,10 @@
using System;
+using System.Collections.Generic;
using System.IO;
using Autofac;
using Autofac.Core;
using Autofac.Core.Registration;
using Kyoo.Controllers;
-using Kyoo.Models.Attributes;
using Kyoo.Models.Options;
using Kyoo.Models.Permissions;
using Kyoo.Tasks;
@@ -13,6 +13,7 @@ using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
+using Microsoft.Extensions.Hosting;
namespace Kyoo
{
@@ -30,18 +31,23 @@ namespace Kyoo
///
public string Description => "The core module containing default implementations.";
+ ///
+ public Dictionary Configuration => new()
+ {
+ { BasicOptions.Path, typeof(BasicOptions) },
+ { TaskOptions.Path, typeof(TaskOptions) },
+ { MediaOptions.Path, typeof(MediaOptions) },
+ { "database", null },
+ { "logging", null }
+ };
+
///
/// The configuration to use.
///
private readonly IConfiguration _configuration;
-
- ///
- /// The configuration manager used to register typed/untyped implementations.
- ///
- [Injected] public IConfigurationManager ConfigurationManager { private get; set; }
-
+
///
/// Create a new core module instance and use the given configuration.
///
@@ -99,10 +105,6 @@ namespace Kyoo
{
string publicUrl = _configuration.GetPublicUrl();
- services.Configure(_configuration.GetSection(BasicOptions.Path));
- services.Configure(_configuration.GetSection(TaskOptions.Path));
- services.Configure(_configuration.GetSection(MediaOptions.Path));
-
services.AddControllers()
.AddNewtonsoftJson(x =>
{
@@ -114,26 +116,30 @@ namespace Kyoo
}
///
- public void ConfigureAspNet(IApplicationBuilder app)
+ public IEnumerable ConfigureSteps => new IStartupAction[]
{
- ConfigurationManager.AddTyped(BasicOptions.Path);
- ConfigurationManager.AddTyped(TaskOptions.Path);
- ConfigurationManager.AddTyped(MediaOptions.Path);
- ConfigurationManager.AddUntyped("database");
- ConfigurationManager.AddUntyped("logging");
-
- FileExtensionContentTypeProvider contentTypeProvider = new();
- contentTypeProvider.Mappings[".data"] = "application/octet-stream";
- app.UseStaticFiles(new StaticFileOptions
+ SA.New((app, env) =>
{
- ContentTypeProvider = contentTypeProvider,
- FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
- });
-
- app.UseEndpoints(endpoints =>
+ if (env.IsDevelopment())
+ app.UseDeveloperExceptionPage();
+ else
+ {
+ app.UseExceptionHandler("/error");
+ app.UseHsts();
+ }
+ }, SA.Before),
+ SA.New(app => app.UseRouting(), SA.Routing),
+ SA.New(app =>
{
- endpoints.MapControllers();
- });
- }
+ FileExtensionContentTypeProvider contentTypeProvider = new();
+ contentTypeProvider.Mappings[".data"] = "application/octet-stream";
+ app.UseStaticFiles(new StaticFileOptions
+ {
+ ContentTypeProvider = contentTypeProvider,
+ FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
+ });
+ }, SA.StaticFiles),
+ SA.New(app => app.UseEndpoints(x => x.MapControllers()), SA.Endpoint)
+ };
}
}
\ No newline at end of file
diff --git a/Kyoo/Helper.cs b/Kyoo/Helper.cs
index 244f6eec..ad8a6dfb 100644
--- a/Kyoo/Helper.cs
+++ b/Kyoo/Helper.cs
@@ -1,32 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Net.Http;
-using System.Reflection;
using System.Threading.Tasks;
-using JetBrains.Annotations;
-using Kyoo.Models.Attributes;
using Newtonsoft.Json;
namespace Kyoo
{
public static class Helper
{
- ///
- /// Inject services into the marked properties of the given object.
- ///
- /// The object to inject
- /// The function used to retrieve services. (The function is called immediately)
- public static void InjectServices(object obj, [InstantHandle] Func retrieve)
- {
- IEnumerable properties = obj.GetType().GetProperties()
- .Where(x => x.GetCustomAttribute() != null)
- .Where(x => x.CanWrite);
-
- foreach (PropertyInfo property in properties)
- property.SetValue(obj, retrieve(property.PropertyType));
- }
-
///
/// An helper method to get json content from an http server. This is a temporary thing and will probably be
/// replaced by a call to the function of the same name in the System.Net.Http.Json namespace when .net6
diff --git a/Kyoo/PluginsStartup.cs b/Kyoo/PluginsStartup.cs
index e279cb57..33305f6e 100644
--- a/Kyoo/PluginsStartup.cs
+++ b/Kyoo/PluginsStartup.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using Autofac;
using Autofac.Extras.AttributeMetadata;
using Kyoo.Authentication;
@@ -90,18 +91,9 @@ namespace Kyoo
/// The host environment (is the app in development mode?)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider provider)
{
- if (env.IsDevelopment())
- app.UseDeveloperExceptionPage();
- else
- {
- app.UseExceptionHandler("/error");
- app.UseHsts();
- }
-
if (!env.IsDevelopment())
app.UseSpaStaticFiles();
-
- app.UseRouting();
+
app.Use((ctx, next) =>
{
ctx.Response.Headers.Remove("X-Powered-By");
@@ -116,9 +108,11 @@ namespace Kyoo
});
app.UseResponseCompression();
- if (_plugins is PluginManager manager)
- manager.SetProvider(provider);
- _plugins.ConfigureAspnet(app);
+ IEnumerable steps = _plugins.GetAllPlugins()
+ .SelectMany(x => x.ConfigureSteps)
+ .OrderByDescending(x => x.Priority);
+ foreach (IStartupAction step in steps)
+ step.Run(provider);
app.UseSpa(spa =>
{
diff --git a/Kyoo/Program.cs b/Kyoo/Program.cs
index 064cb6e7..cd16ca95 100644
--- a/Kyoo/Program.cs
+++ b/Kyoo/Program.cs
@@ -28,8 +28,8 @@ namespace Kyoo
[SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")]
public static async Task Main(string[] args)
{
- if (!File.Exists("./settings.json"))
- File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "settings.json"), "settings.json");
+ if (!File.Exists(JsonConfigPath))
+ File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, JsonConfigPath), JsonConfigPath);
IHostBuilder builder = CreateWebHostBuilder(args);
@@ -77,7 +77,8 @@ namespace Kyoo
/// The modified configuration builder
private static IConfigurationBuilder SetupConfig(IConfigurationBuilder builder, string[] args)
{
- return builder.AddJsonFile(JsonConfigPath, false, true)
+ return builder.SetBasePath(Environment.CurrentDirectory)
+ .AddJsonFile(JsonConfigPath, false, true)
.AddEnvironmentVariables()
.AddCommandLine(args);
}