mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-30 19:54:16 -04:00
Removing UnityContainer and fixing service loading
This commit is contained in:
parent
a18f393926
commit
3e8dbc84a8
@ -62,7 +62,7 @@ namespace Kyoo.Authentication
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public IServiceCollection Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||||
{
|
{
|
||||||
string publicUrl = _configuration.GetValue<string>("public_url");
|
string publicUrl = _configuration.GetValue<string>("public_url");
|
||||||
|
|
||||||
@ -148,7 +148,6 @@ namespace Kyoo.Authentication
|
|||||||
AllowedOrigins = {new Uri(publicUrl).GetLeftPart(UriPartial.Authority)}
|
AllowedOrigins = {new Uri(publicUrl).GetLeftPart(UriPartial.Authority)}
|
||||||
};
|
};
|
||||||
services.AddSingleton<ICorsPolicyService>(cors);
|
services.AddSingleton<ICorsPolicyService>(cors);
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Unity;
|
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
@ -59,30 +58,14 @@ namespace Kyoo.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A configure method that will be run on plugin's startup.
|
/// A configure method that will be run on plugin's startup.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container">A unity container to register new services.</param>
|
/// <param name="services">A service container to register new services.</param>
|
||||||
/// <param name="availableTypes">The list of types that are available for this instance. This can be used
|
/// <param name="availableTypes">The list of types that are available for this instance. This can be used
|
||||||
/// for conditional type. See <see cref="ProviderCondition.Has(System.Type,System.Collections.Generic.ICollection{System.Type})"/>
|
/// for conditional type. See <see cref="ProviderCondition.Has(System.Type,System.Collections.Generic.ICollection{System.Type})"/>
|
||||||
/// or <see cref="ProviderCondition.Has(System.Collections.Generic.ICollection{System.Type},System.Collections.Generic.ICollection{System.Type})"/>></param>
|
/// or <see cref="ProviderCondition.Has(System.Collections.Generic.ICollection{System.Type},System.Collections.Generic.ICollection{System.Type})"/>>
|
||||||
void Configure(IUnityContainer container, ICollection<Type> availableTypes) {}
|
/// You can't simply check on the service collection because some dependencies might be registered after your plugin.
|
||||||
|
/// </param>
|
||||||
|
void Configure(IServiceCollection services, ICollection<Type> availableTypes);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// An optional configure method that will be run on plugin's startup.
|
|
||||||
/// This method may be used instead or with the
|
|
||||||
/// <see cref="Configure(Unity.IUnityContainer,System.Collections.Generic.ICollection{System.Type})"/> method
|
|
||||||
/// if you use a library that configure itself with a <see cref="IServiceCollection"/>.
|
|
||||||
/// Every service put in this container will be registered to the unity container after this method.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="services">An empty service container to register new services.</param>
|
|
||||||
/// <param name="availableTypes">The list of types that are available for this instance. This can be used
|
|
||||||
/// for conditional type. See <see cref="ProviderCondition.Has(System.Type,System.Collections.Generic.ICollection{System.Type})"/>
|
|
||||||
/// or <see cref="ProviderCondition.Has(System.Collections.Generic.ICollection{System.Type},System.Collections.Generic.ICollection{System.Type})"/>></param>
|
|
||||||
/// <returns>You should return the <see cref="services"/> parameter or another container if you want.
|
|
||||||
/// This container will be added to Kyoo's unity container.</returns>
|
|
||||||
IServiceCollection Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
|
||||||
{
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An optional configuration step to allow a plugin to change asp net configurations.
|
/// 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.
|
/// WARNING: This is only called on Kyoo's startup so you must restart the app to apply this changes.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Kyoo.Models.Exceptions;
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
@ -29,11 +31,26 @@ namespace Kyoo.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>All plugins currently loaded.</returns>
|
/// <returns>All plugins currently loaded.</returns>
|
||||||
public ICollection<IPlugin> GetAllPlugins();
|
public ICollection<IPlugin> GetAllPlugins();
|
||||||
|
|
||||||
|
/// <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(ICollection<IPlugin> plugins);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configure services adding or removing services as the plugins wants.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">The service collection to populate</param>
|
||||||
|
public void ConfigureServices(IServiceCollection services);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load new plugins from the plugin directory.
|
/// Configure an asp net application applying plugins policies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <exception cref="MissingDependencyException">If a plugin can't be loaded because a dependency can't be resolved.</exception>
|
/// <param name="app">The asp net application to configure</param>
|
||||||
public void ReloadPlugins();
|
public void ConfigureAspnet(IApplicationBuilder app);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,14 +24,8 @@
|
|||||||
<PackageReference Include="JetBrains.Annotations" Version="2021.1.0" />
|
<PackageReference Include="JetBrains.Annotations" Version="2021.1.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Abstractions" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.0-beta-20204-02" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.0-beta-20204-02" PrivateAssets="All" />
|
||||||
<PackageReference Include="Unity.Abstractions" Version="5.11.7" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60">
|
|
||||||
<HintPath>..\..\..\..\..\..\usr\share\dotnet\shared\Microsoft.AspNetCore.App\5.0.5\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Unity;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Kyoo
|
namespace Kyoo
|
||||||
{
|
{
|
||||||
@ -12,55 +12,55 @@ namespace Kyoo
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register a new task to the container.
|
/// Register a new task to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container">The container</param>
|
/// <param name="services">The container</param>
|
||||||
/// <typeparam name="T">The type of the task</typeparam>
|
/// <typeparam name="T">The type of the task</typeparam>
|
||||||
/// <returns>The initial container.</returns>
|
/// <returns>The initial container.</returns>
|
||||||
public static IUnityContainer RegisterTask<T>(this IUnityContainer container)
|
public static IServiceCollection AddTask<T>(this IServiceCollection services)
|
||||||
where T : class, ITask
|
where T : class, ITask
|
||||||
{
|
{
|
||||||
container.RegisterType<ITask, T>();
|
services.AddSingleton<ITask, T>();
|
||||||
return container;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register a new repository to the container.
|
/// Register a new repository to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container">The container</param>
|
/// <param name="services">The container</param>
|
||||||
|
/// <param name="lifetime">The lifetime of the repository. The default is scoped.</param>
|
||||||
/// <typeparam name="T">The type of the repository.</typeparam>
|
/// <typeparam name="T">The type of the repository.</typeparam>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// If your repository implements a special interface, please use <see cref="RegisterRepository{T,T}"/>
|
/// If your repository implements a special interface, please use <see cref="AddRepository{T,T2}"/>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>The initial container.</returns>
|
/// <returns>The initial container.</returns>
|
||||||
public static IUnityContainer RegisterRepository<T>(this IUnityContainer container)
|
public static IServiceCollection AddRepository<T>(this IServiceCollection services,
|
||||||
|
ServiceLifetime lifetime = ServiceLifetime.Scoped)
|
||||||
where T : IBaseRepository
|
where T : IBaseRepository
|
||||||
{
|
{
|
||||||
Type repository = Utility.GetGenericDefinition(typeof(T), typeof(IRepository<>));
|
Type repository = Utility.GetGenericDefinition(typeof(T), typeof(IRepository<>));
|
||||||
|
|
||||||
if (repository != null)
|
if (repository != null)
|
||||||
{
|
services.Add(ServiceDescriptor.Describe(repository, typeof(T), lifetime));
|
||||||
container.RegisterType(repository, typeof(T));
|
services.Add(ServiceDescriptor.Describe(typeof(IBaseRepository), typeof(T), lifetime));
|
||||||
container.RegisterType<IBaseRepository, T>(repository.FriendlyName());
|
return services;
|
||||||
}
|
|
||||||
else
|
|
||||||
container.RegisterType<IBaseRepository, T>(typeof(T).FriendlyName());
|
|
||||||
return container;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Register a new repository with a custom mapping to the container.
|
/// Register a new repository with a custom mapping to the container.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container"></param>
|
/// <param name="services"></param>
|
||||||
|
/// <param name="lifetime">The lifetime of the repository. The default is scoped.</param>
|
||||||
/// <typeparam name="T">The custom mapping you have for your repository.</typeparam>
|
/// <typeparam name="T">The custom mapping you have for your repository.</typeparam>
|
||||||
/// <typeparam name="T2">The type of the repository.</typeparam>
|
/// <typeparam name="T2">The type of the repository.</typeparam>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// If your repository does not implements a special interface, please use <see cref="RegisterRepository{T}"/>
|
/// If your repository does not implements a special interface, please use <see cref="AddRepository{T}"/>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <returns>The initial container.</returns>
|
/// <returns>The initial container.</returns>
|
||||||
public static IUnityContainer RegisterRepository<T, T2>(this IUnityContainer container)
|
public static IServiceCollection AddRepository<T, T2>(this IServiceCollection services,
|
||||||
|
ServiceLifetime lifetime = ServiceLifetime.Scoped)
|
||||||
where T2 : IBaseRepository, T
|
where T2 : IBaseRepository, T
|
||||||
{
|
{
|
||||||
container.RegisterType<T, T2>();
|
services.Add(ServiceDescriptor.Describe(typeof(T), typeof(T2), lifetime));
|
||||||
return container.RegisterRepository<T2>();
|
return services.AddRepository<T2>(lifetime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
|||||||
using Kyoo.Controllers;
|
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.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Unity;
|
|
||||||
|
|
||||||
namespace Kyoo.Postgresql
|
namespace Kyoo.Postgresql
|
||||||
{
|
{
|
||||||
@ -57,9 +57,9 @@ namespace Kyoo.Postgresql
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Configure(IUnityContainer container, ICollection<Type> availableTypes)
|
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||||
{
|
{
|
||||||
container.RegisterFactory<DatabaseContext>(_ => new PostgresContext(
|
services.AddScoped<DatabaseContext>(_ => new PostgresContext(
|
||||||
_configuration.GetDatabaseConnection("postgres"),
|
_configuration.GetDatabaseConnection("postgres"),
|
||||||
_environment.IsDevelopment()));
|
_environment.IsDevelopment()));
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,10 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
using Kyoo.Models.Exceptions;
|
using Kyoo.Models.Exceptions;
|
||||||
using Kyoo.UnityExtensions;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Unity;
|
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
@ -20,9 +19,9 @@ namespace Kyoo.Controllers
|
|||||||
public class PluginManager : IPluginManager
|
public class PluginManager : IPluginManager
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The unity container. It is given to the Configure method of plugins.
|
/// The service provider. It allow plugin's activation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IUnityContainer _container;
|
private readonly IServiceProvider _provider;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The configuration to get the plugin's directory.
|
/// The configuration to get the plugin's directory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -40,14 +39,14 @@ namespace Kyoo.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="PluginManager"/> instance.
|
/// Create a new <see cref="PluginManager"/> instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="container">A unity container to allow plugins to register new entries</param>
|
/// <param name="provider">A service container to allow initialization of plugins</param>
|
||||||
/// <param name="config">The configuration instance, to get the plugin's directory path.</param>
|
/// <param name="config">The configuration instance, to get the plugin's directory path.</param>
|
||||||
/// <param name="logger">The logger used by this class.</param>
|
/// <param name="logger">The logger used by this class.</param>
|
||||||
public PluginManager(IUnityContainer container,
|
public PluginManager(IServiceProvider provider,
|
||||||
IConfiguration config,
|
IConfiguration config,
|
||||||
ILogger<PluginManager> logger)
|
ILogger<PluginManager> logger)
|
||||||
{
|
{
|
||||||
_container = container;
|
_provider = provider;
|
||||||
_config = config;
|
_config = config;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
@ -72,7 +71,7 @@ namespace Kyoo.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ReloadPlugins()
|
public void LoadPlugins(ICollection<IPlugin> plugins)
|
||||||
{
|
{
|
||||||
string pluginFolder = _config.GetValue<string>("plugins");
|
string pluginFolder = _config.GetValue<string>("plugins");
|
||||||
if (!Directory.Exists(pluginFolder))
|
if (!Directory.Exists(pluginFolder))
|
||||||
@ -80,7 +79,7 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
_logger.LogTrace("Loading new plugins...");
|
_logger.LogTrace("Loading new plugins...");
|
||||||
string[] pluginsPaths = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);
|
string[] pluginsPaths = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);
|
||||||
ICollection<IPlugin> newPlugins = pluginsPaths.SelectMany(path =>
|
plugins = pluginsPaths.SelectMany(path =>
|
||||||
{
|
{
|
||||||
path = Path.GetFullPath(path);
|
path = Path.GetFullPath(path);
|
||||||
try
|
try
|
||||||
@ -90,7 +89,7 @@ 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)ActivatorUtilities.CreateInstance(_provider, x))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -98,32 +97,40 @@ namespace Kyoo.Controllers
|
|||||||
_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>();
|
||||||
}
|
}
|
||||||
}).ToList();
|
}).Concat(plugins).ToList();
|
||||||
if (!_plugins.Any())
|
|
||||||
newPlugins.Add(new CoreModule());
|
|
||||||
_plugins.AddRange(newPlugins);
|
|
||||||
|
|
||||||
ICollection<Type> available = GetProvidedTypes();
|
ICollection<Type> available = GetProvidedTypes();
|
||||||
foreach (IPlugin plugin in newPlugins)
|
_plugins.AddRange(plugins.Where(plugin =>
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
return true;
|
||||||
Exception error = new MissingDependencyException(plugin.Name, missing.Name);
|
|
||||||
_logger.LogCritical(error, "A plugin's dependency could not be met");
|
Exception error = new MissingDependencyException(plugin.Name, missing.Name);
|
||||||
}
|
_logger.LogCritical(error, "A plugin's dependency could not be met");
|
||||||
else
|
return false;
|
||||||
{
|
}));
|
||||||
plugin.Configure(_container, available);
|
|
||||||
_container.AddServices(plugin.Configure(new ServiceCollection(), available));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_plugins.Any())
|
if (!_plugins.Any())
|
||||||
_logger.LogInformation("No plugin enabled");
|
_logger.LogInformation("No plugin enabled");
|
||||||
else
|
else
|
||||||
_logger.LogInformation("Plugin enabled: {Plugins}", _plugins.Select(x => x.Name));
|
_logger.LogInformation("Plugin enabled: {Plugins}", _plugins.Select(x => x.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
ICollection<Type> available = GetProvidedTypes();
|
||||||
|
foreach (IPlugin plugin in _plugins)
|
||||||
|
plugin.Configure(services, available);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void ConfigureAspnet(IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
foreach (IPlugin plugin in _plugins)
|
||||||
|
plugin.ConfigureAspNet(app);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the list of types provided by the currently loaded plugins.
|
/// Get the list of types provided by the currently loaded plugins.
|
||||||
|
@ -9,7 +9,6 @@ using Kyoo.Models.Exceptions;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Unity;
|
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
@ -22,7 +21,7 @@ namespace Kyoo.Controllers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The service provider used to activate
|
/// The service provider used to activate
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IUnityContainer _container;
|
private readonly IServiceProvider _provider;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The configuration instance used to get schedule information
|
/// The configuration instance used to get schedule information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -54,15 +53,15 @@ namespace Kyoo.Controllers
|
|||||||
/// Create a new <see cref="TaskManager"/>.
|
/// Create a new <see cref="TaskManager"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tasks">The list of tasks to manage</param>
|
/// <param name="tasks">The list of tasks to manage</param>
|
||||||
/// <param name="container">The service provider to request services for tasks</param>
|
/// <param name="provider">The service provider to request services for tasks</param>
|
||||||
/// <param name="configuration">The configuration to load schedule information.</param>
|
/// <param name="configuration">The configuration to load schedule information.</param>
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
public TaskManager(IEnumerable<ITask> tasks,
|
public TaskManager(IEnumerable<ITask> tasks,
|
||||||
IUnityContainer container,
|
IServiceProvider provider,
|
||||||
IConfiguration configuration,
|
IConfiguration configuration,
|
||||||
ILogger<TaskManager> logger)
|
ILogger<TaskManager> logger)
|
||||||
{
|
{
|
||||||
_container = container;
|
_provider = provider;
|
||||||
_configuration = configuration.GetSection("scheduledTasks");
|
_configuration = configuration.GetSection("scheduledTasks");
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_tasks = tasks.Select(x => (x, DateTime.Now + GetTaskDelay(x.Slug))).ToList();
|
_tasks = tasks.Select(x => (x, DateTime.Now + GetTaskDelay(x.Slug))).ToList();
|
||||||
@ -173,7 +172,7 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
foreach (PropertyInfo property in properties)
|
foreach (PropertyInfo property in properties)
|
||||||
{
|
{
|
||||||
object value = _container.Resolve(property.PropertyType);
|
object value = _provider.GetService(property.PropertyType);
|
||||||
property.SetValue(obj, value);
|
property.SetValue(obj, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,7 +243,7 @@ namespace Kyoo.Controllers
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ReloadTasks()
|
public void ReloadTasks()
|
||||||
{
|
{
|
||||||
_tasks = _container.Resolve<IEnumerable<ITask>>().Select(x => (x, DateTime.Now + GetTaskDelay(x.Slug))).ToList();
|
// _tasks = _provider.Resolve<IEnumerable<ITask>>().Select(x => (x, DateTime.Now + GetTaskDelay(x.Slug))).ToList();
|
||||||
EnqueueStartupTasks();
|
EnqueueStartupTasks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Tasks;
|
using Kyoo.Tasks;
|
||||||
using Unity;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Unity.Lifetime;
|
|
||||||
|
|
||||||
namespace Kyoo
|
namespace Kyoo
|
||||||
{
|
{
|
||||||
@ -52,32 +51,33 @@ namespace Kyoo
|
|||||||
public ICollection<Type> Requires => ArraySegment<Type>.Empty;
|
public ICollection<Type> Requires => ArraySegment<Type>.Empty;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Configure(IUnityContainer container, ICollection<Type> availableTypes)
|
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||||
{
|
{
|
||||||
container.RegisterType<IFileManager, FileManager>(new SingletonLifetimeManager());
|
services.AddSingleton<IFileManager, FileManager>();
|
||||||
container.RegisterType<ITranscoder, Transcoder>(new SingletonLifetimeManager());
|
services.AddSingleton<ITranscoder, Transcoder>();
|
||||||
container.RegisterType<IThumbnailsManager, ThumbnailsManager>(new SingletonLifetimeManager());
|
services.AddSingleton<IThumbnailsManager, ThumbnailsManager>();
|
||||||
container.RegisterType<IProviderManager, ProviderManager>(new SingletonLifetimeManager());
|
services.AddSingleton<IProviderManager, ProviderManager>();
|
||||||
container.RegisterType<ITaskManager, TaskManager>(new SingletonLifetimeManager());
|
services.AddSingleton<ITaskManager, TaskManager>();
|
||||||
|
services.AddHostedService(x => x.GetService<ITaskManager>() as TaskManager);
|
||||||
|
|
||||||
container.RegisterType<ILibraryManager, LibraryManager>(new HierarchicalLifetimeManager());
|
services.AddScoped<ILibraryManager, LibraryManager>();
|
||||||
|
|
||||||
if (ProviderCondition.Has(typeof(DatabaseContext), availableTypes))
|
if (ProviderCondition.Has(typeof(DatabaseContext), availableTypes))
|
||||||
{
|
{
|
||||||
container.RegisterRepository<ILibraryRepository, LibraryRepository>();
|
services.AddRepository<ILibraryRepository, LibraryRepository>();
|
||||||
container.RegisterRepository<ILibraryItemRepository, LibraryItemRepository>();
|
services.AddRepository<ILibraryItemRepository, LibraryItemRepository>();
|
||||||
container.RegisterRepository<ICollectionRepository, CollectionRepository>();
|
services.AddRepository<ICollectionRepository, CollectionRepository>();
|
||||||
container.RegisterRepository<IShowRepository, ShowRepository>();
|
services.AddRepository<IShowRepository, ShowRepository>();
|
||||||
container.RegisterRepository<ISeasonRepository, SeasonRepository>();
|
services.AddRepository<ISeasonRepository, SeasonRepository>();
|
||||||
container.RegisterRepository<IEpisodeRepository, EpisodeRepository>();
|
services.AddRepository<IEpisodeRepository, EpisodeRepository>();
|
||||||
container.RegisterRepository<ITrackRepository, TrackRepository>();
|
services.AddRepository<ITrackRepository, TrackRepository>();
|
||||||
container.RegisterRepository<IPeopleRepository, PeopleRepository>();
|
services.AddRepository<IPeopleRepository, PeopleRepository>();
|
||||||
container.RegisterRepository<IStudioRepository, StudioRepository>();
|
services.AddRepository<IStudioRepository, StudioRepository>();
|
||||||
container.RegisterRepository<IGenreRepository, GenreRepository>();
|
services.AddRepository<IGenreRepository, GenreRepository>();
|
||||||
container.RegisterRepository<IProviderRepository, ProviderRepository>();
|
services.AddRepository<IProviderRepository, ProviderRepository>();
|
||||||
}
|
}
|
||||||
|
|
||||||
container.RegisterTask<Crawler>();
|
services.AddTask<Crawler>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -47,8 +47,6 @@
|
|||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="Unity.Container" Version="5.11.11" />
|
|
||||||
<PackageReference Include="Unity.Microsoft.DependencyInjection" Version="5.11.5" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
12
Kyoo/Models/LazyDi.cs
Normal file
12
Kyoo/Models/LazyDi.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Kyoo.Models
|
||||||
|
{
|
||||||
|
public class LazyDi<T> : Lazy<T>
|
||||||
|
{
|
||||||
|
public LazyDi(IServiceProvider provider)
|
||||||
|
: base(provider.GetRequiredService<T>)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.UnityExtensions;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Hosting.StaticWebAssets;
|
using Microsoft.AspNetCore.Hosting.StaticWebAssets;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Unity;
|
|
||||||
using Unity.Microsoft.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Kyoo
|
namespace Kyoo
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -80,9 +76,6 @@ namespace Kyoo
|
|||||||
/// <returns>A new web host instance</returns>
|
/// <returns>A new web host instance</returns>
|
||||||
private static IWebHostBuilder CreateWebHostBuilder(string[] args)
|
private static IWebHostBuilder CreateWebHostBuilder(string[] args)
|
||||||
{
|
{
|
||||||
UnityContainer container = new();
|
|
||||||
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())
|
||||||
@ -100,8 +93,6 @@ namespace Kyoo
|
|||||||
if (context.HostingEnvironment.IsDevelopment())
|
if (context.HostingEnvironment.IsDevelopment())
|
||||||
StaticWebAssetsLoader.UseStaticWebAssets(context.HostingEnvironment, context.Configuration);
|
StaticWebAssetsLoader.UseStaticWebAssets(context.HostingEnvironment, context.Configuration);
|
||||||
})
|
})
|
||||||
// .UseUnityProvider(container)
|
|
||||||
.UseUnityServiceProvider(container)
|
|
||||||
.ConfigureServices(x => x.AddRouting())
|
.ConfigureServices(x => x.AddRouting())
|
||||||
.UseKestrel(options => { options.AddServerHeader = false; })
|
.UseKestrel(options => { options.AddServerHeader = false; })
|
||||||
.UseIIS()
|
.UseIIS()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
|
using Kyoo.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.SpaServices.AngularCli;
|
using Microsoft.AspNetCore.SpaServices.AngularCli;
|
||||||
@ -10,8 +11,6 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Unity;
|
|
||||||
using Unity.Lifetime;
|
|
||||||
|
|
||||||
namespace Kyoo
|
namespace Kyoo
|
||||||
{
|
{
|
||||||
@ -20,16 +19,38 @@ namespace Kyoo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Startup
|
public class Startup
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The configuration context
|
||||||
|
/// </summary>
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
/// <summary>
|
||||||
|
/// A plugin manager used to load plugins and allow them to configure services / asp net.
|
||||||
|
/// </summary>
|
||||||
|
private readonly IPluginManager _plugins;
|
||||||
|
|
||||||
|
|
||||||
public Startup(IConfiguration configuration, ILoggerFactory loggerFactory, IServiceProvider provider)
|
/// <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>
|
||||||
|
/// <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)
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
_configuration = configuration;
|
||||||
_loggerFactory = loggerFactory;
|
_plugins = new PluginManager(hostProvider, _configuration, loggerFactory.CreateLogger<PluginManager>());
|
||||||
|
|
||||||
|
_plugins.LoadPlugins(new [] {new CoreModule()});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configure the WebApp services context.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">The service collection to fill.</param>
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
string publicUrl = _configuration.GetValue<string>("public_url");
|
string publicUrl = _configuration.GetValue<string>("public_url");
|
||||||
@ -63,23 +84,18 @@ namespace Kyoo
|
|||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
// services.AddAuthentication()
|
// services.AddAuthentication()
|
||||||
|
|
||||||
|
|
||||||
// container.Resolve<IConfiguration>();
|
services.AddSingleton(_plugins);
|
||||||
|
services.AddTransient(typeof(Lazy<>), typeof(LazyDi<>));
|
||||||
services.AddSingleton<ITaskManager, TaskManager>();
|
_plugins.ConfigureServices(services);
|
||||||
services.AddHostedService(x => x.GetService<ITaskManager>() as TaskManager);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ConfigureContainer(IUnityContainer container)
|
|
||||||
{
|
|
||||||
container.RegisterType<IPluginManager, PluginManager>(new SingletonLifetimeManager());
|
|
||||||
container.RegisterInstance(_configuration);
|
|
||||||
PluginManager pluginManager = new(container, _configuration, _loggerFactory.CreateLogger<PluginManager>());
|
|
||||||
pluginManager.ReloadPlugins();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IUnityContainer container, IApplicationBuilder app, IWebHostEnvironment env)
|
/// <summary>
|
||||||
|
/// Configure the asp net host.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="app">The asp net host to configure</param>
|
||||||
|
/// <param name="env">The host environment (is the app in development mode?)</param>
|
||||||
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||||
{
|
{
|
||||||
if (env.IsDevelopment())
|
if (env.IsDevelopment())
|
||||||
app.UseDeveloperExceptionPage();
|
app.UseDeveloperExceptionPage();
|
||||||
@ -124,9 +140,7 @@ namespace Kyoo
|
|||||||
spa.UseAngularCliServer("start");
|
spa.UseAngularCliServer("start");
|
||||||
});
|
});
|
||||||
|
|
||||||
IPluginManager pluginManager = container.Resolve<IPluginManager>();
|
_plugins.ConfigureAspnet(app);
|
||||||
foreach (IPlugin plugin in pluginManager.GetAllPlugins())
|
|
||||||
plugin.ConfigureAspNet(app);
|
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using Unity;
|
|
||||||
using Unity.Microsoft.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Kyoo.UnityExtensions
|
|
||||||
{
|
|
||||||
public static class UnityExtensions
|
|
||||||
{
|
|
||||||
public static IWebHostBuilder UseUnityProvider(this IWebHostBuilder host, UnityContainer container)
|
|
||||||
{
|
|
||||||
UnityProvider factory = new(container);
|
|
||||||
|
|
||||||
return host.ConfigureServices((_, services) =>
|
|
||||||
{
|
|
||||||
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<UnityContainer>>(factory));
|
|
||||||
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IUnityContainer>>(factory));
|
|
||||||
services.Replace(ServiceDescriptor.Singleton<IServiceProviderFactory<IServiceCollection>>(factory));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IUnityContainer AddServices(this IUnityContainer container, IServiceCollection services)
|
|
||||||
{
|
|
||||||
return (IUnityContainer)typeof(ServiceProviderExtensions).Assembly
|
|
||||||
.GetType("Unity.Microsoft.DependencyInjection.Configuration")
|
|
||||||
!.GetMethod("AddServices", BindingFlags.Static | BindingFlags.NonPublic)
|
|
||||||
!.Invoke(null, new object[] {container, services});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Unity;
|
|
||||||
using Unity.Microsoft.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Kyoo.UnityExtensions
|
|
||||||
{
|
|
||||||
public class UnityProvider : ServiceProviderFactory, IServiceProviderFactory<UnityContainer>
|
|
||||||
{
|
|
||||||
private readonly UnityContainer _container;
|
|
||||||
|
|
||||||
|
|
||||||
public UnityProvider(UnityContainer container)
|
|
||||||
: base(container)
|
|
||||||
{
|
|
||||||
_container = container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UnityContainer CreateBuilder(IServiceCollection services)
|
|
||||||
{
|
|
||||||
_container.AddServices(services);
|
|
||||||
return _container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IServiceProvider CreateServiceProvider(UnityContainer containerBuilder)
|
|
||||||
{
|
|
||||||
return CreateServiceProvider(containerBuilder as IUnityContainer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user