mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -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 />
|
||||
public IServiceCollection Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
{
|
||||
string publicUrl = _configuration.GetValue<string>("public_url");
|
||||
|
||||
@ -148,7 +148,6 @@ namespace Kyoo.Authentication
|
||||
AllowedOrigins = {new Uri(publicUrl).GetLeftPart(UriPartial.Authority)}
|
||||
};
|
||||
services.AddSingleton<ICorsPolicyService>(cors);
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -4,7 +4,6 @@ using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Unity;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
@ -59,29 +58,13 @@ namespace Kyoo.Controllers
|
||||
/// <summary>
|
||||
/// A configure method that will be run on plugin's startup.
|
||||
/// </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
|
||||
/// 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>
|
||||
void Configure(IUnityContainer container, 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;
|
||||
}
|
||||
/// or <see cref="ProviderCondition.Has(System.Collections.Generic.ICollection{System.Type},System.Collections.Generic.ICollection{System.Type})"/>>
|
||||
/// 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 configuration step to allow a plugin to change asp net configurations.
|
||||
|
@ -1,5 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
@ -31,9 +33,24 @@ namespace Kyoo.Controllers
|
||||
public ICollection<IPlugin> GetAllPlugins();
|
||||
|
||||
/// <summary>
|
||||
/// Load new plugins from the plugin directory.
|
||||
/// Load plugins and their dependencies from the plugin directory.
|
||||
/// </summary>
|
||||
/// <exception cref="MissingDependencyException">If a plugin can't be loaded because a dependency can't be resolved.</exception>
|
||||
public void ReloadPlugins();
|
||||
/// <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>
|
||||
/// Configure an asp net application applying plugins policies.
|
||||
/// </summary>
|
||||
/// <param name="app">The asp net application to configure</param>
|
||||
public void ConfigureAspnet(IApplicationBuilder app);
|
||||
}
|
||||
}
|
@ -24,14 +24,8 @@
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2021.1.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.DependencyInjection.Abstractions" Version="5.0.0" />
|
||||
<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>
|
||||
|
||||
</Project>
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using Kyoo.Controllers;
|
||||
using Unity;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo
|
||||
{
|
||||
@ -12,55 +12,55 @@ namespace Kyoo
|
||||
/// <summary>
|
||||
/// Register a new task to the container.
|
||||
/// </summary>
|
||||
/// <param name="container">The container</param>
|
||||
/// <param name="services">The container</param>
|
||||
/// <typeparam name="T">The type of the task</typeparam>
|
||||
/// <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
|
||||
{
|
||||
container.RegisterType<ITask, T>();
|
||||
return container;
|
||||
services.AddSingleton<ITask, T>();
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register a new repository to the container.
|
||||
/// </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>
|
||||
/// <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>
|
||||
/// <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
|
||||
{
|
||||
Type repository = Utility.GetGenericDefinition(typeof(T), typeof(IRepository<>));
|
||||
|
||||
if (repository != null)
|
||||
{
|
||||
container.RegisterType(repository, typeof(T));
|
||||
container.RegisterType<IBaseRepository, T>(repository.FriendlyName());
|
||||
}
|
||||
else
|
||||
container.RegisterType<IBaseRepository, T>(typeof(T).FriendlyName());
|
||||
return container;
|
||||
services.Add(ServiceDescriptor.Describe(repository, typeof(T), lifetime));
|
||||
services.Add(ServiceDescriptor.Describe(typeof(IBaseRepository), typeof(T), lifetime));
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register a new repository with a custom mapping to the container.
|
||||
/// </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="T2">The type of the repository.</typeparam>
|
||||
/// <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>
|
||||
/// <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
|
||||
{
|
||||
container.RegisterType<T, T2>();
|
||||
return container.RegisterRepository<T2>();
|
||||
services.Add(ServiceDescriptor.Describe(typeof(T), typeof(T2), lifetime));
|
||||
return services.AddRepository<T2>(lifetime);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Unity;
|
||||
|
||||
namespace Kyoo.Postgresql
|
||||
{
|
||||
@ -57,9 +57,9 @@ namespace Kyoo.Postgresql
|
||||
}
|
||||
|
||||
/// <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"),
|
||||
_environment.IsDevelopment()));
|
||||
}
|
||||
|
@ -5,11 +5,10 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Kyoo.UnityExtensions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Unity;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
@ -20,9 +19,9 @@ namespace Kyoo.Controllers
|
||||
public class PluginManager : IPluginManager
|
||||
{
|
||||
/// <summary>
|
||||
/// The unity container. It is given to the Configure method of plugins.
|
||||
/// The service provider. It allow plugin's activation.
|
||||
/// </summary>
|
||||
private readonly IUnityContainer _container;
|
||||
private readonly IServiceProvider _provider;
|
||||
/// <summary>
|
||||
/// The configuration to get the plugin's directory.
|
||||
/// </summary>
|
||||
@ -40,14 +39,14 @@ namespace Kyoo.Controllers
|
||||
/// <summary>
|
||||
/// Create a new <see cref="PluginManager"/> instance.
|
||||
/// </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="logger">The logger used by this class.</param>
|
||||
public PluginManager(IUnityContainer container,
|
||||
public PluginManager(IServiceProvider provider,
|
||||
IConfiguration config,
|
||||
ILogger<PluginManager> logger)
|
||||
{
|
||||
_container = container;
|
||||
_provider = provider;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
}
|
||||
@ -72,7 +71,7 @@ namespace Kyoo.Controllers
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ReloadPlugins()
|
||||
public void LoadPlugins(ICollection<IPlugin> plugins)
|
||||
{
|
||||
string pluginFolder = _config.GetValue<string>("plugins");
|
||||
if (!Directory.Exists(pluginFolder))
|
||||
@ -80,7 +79,7 @@ namespace Kyoo.Controllers
|
||||
|
||||
_logger.LogTrace("Loading new plugins...");
|
||||
string[] pluginsPaths = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);
|
||||
ICollection<IPlugin> newPlugins = pluginsPaths.SelectMany(path =>
|
||||
plugins = pluginsPaths.SelectMany(path =>
|
||||
{
|
||||
path = Path.GetFullPath(path);
|
||||
try
|
||||
@ -90,7 +89,7 @@ namespace Kyoo.Controllers
|
||||
return assembly.GetTypes()
|
||||
.Where(x => typeof(IPlugin).IsAssignableFrom(x))
|
||||
.Where(x => _plugins.All(y => y.GetType() != x))
|
||||
.Select(x => (IPlugin)_container.Resolve(x))
|
||||
.Select(x => (IPlugin)ActivatorUtilities.CreateInstance(_provider, x))
|
||||
.ToArray();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -98,26 +97,19 @@ namespace Kyoo.Controllers
|
||||
_logger.LogError(ex, "Could not load the plugin at {Path}", path);
|
||||
return Array.Empty<IPlugin>();
|
||||
}
|
||||
}).ToList();
|
||||
if (!_plugins.Any())
|
||||
newPlugins.Add(new CoreModule());
|
||||
_plugins.AddRange(newPlugins);
|
||||
}).Concat(plugins).ToList();
|
||||
|
||||
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)));
|
||||
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");
|
||||
}
|
||||
else
|
||||
{
|
||||
plugin.Configure(_container, available);
|
||||
_container.AddServices(plugin.Configure(new ServiceCollection(), available));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
|
||||
if (!_plugins.Any())
|
||||
_logger.LogInformation("No plugin enabled");
|
||||
@ -125,6 +117,21 @@ namespace Kyoo.Controllers
|
||||
_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>
|
||||
/// Get the list of types provided by the currently loaded plugins.
|
||||
/// </summary>
|
||||
|
@ -9,7 +9,6 @@ using Kyoo.Models.Exceptions;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Unity;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
@ -22,7 +21,7 @@ namespace Kyoo.Controllers
|
||||
/// <summary>
|
||||
/// The service provider used to activate
|
||||
/// </summary>
|
||||
private readonly IUnityContainer _container;
|
||||
private readonly IServiceProvider _provider;
|
||||
/// <summary>
|
||||
/// The configuration instance used to get schedule information
|
||||
/// </summary>
|
||||
@ -54,15 +53,15 @@ namespace Kyoo.Controllers
|
||||
/// Create a new <see cref="TaskManager"/>.
|
||||
/// </summary>
|
||||
/// <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="logger">The logger.</param>
|
||||
public TaskManager(IEnumerable<ITask> tasks,
|
||||
IUnityContainer container,
|
||||
IServiceProvider provider,
|
||||
IConfiguration configuration,
|
||||
ILogger<TaskManager> logger)
|
||||
{
|
||||
_container = container;
|
||||
_provider = provider;
|
||||
_configuration = configuration.GetSection("scheduledTasks");
|
||||
_logger = logger;
|
||||
_tasks = tasks.Select(x => (x, DateTime.Now + GetTaskDelay(x.Slug))).ToList();
|
||||
@ -173,7 +172,7 @@ namespace Kyoo.Controllers
|
||||
|
||||
foreach (PropertyInfo property in properties)
|
||||
{
|
||||
object value = _container.Resolve(property.PropertyType);
|
||||
object value = _provider.GetService(property.PropertyType);
|
||||
property.SetValue(obj, value);
|
||||
}
|
||||
}
|
||||
@ -244,7 +243,7 @@ namespace Kyoo.Controllers
|
||||
/// <inheritdoc />
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Tasks;
|
||||
using Unity;
|
||||
using Unity.Lifetime;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo
|
||||
{
|
||||
@ -52,32 +51,33 @@ namespace Kyoo
|
||||
public ICollection<Type> Requires => ArraySegment<Type>.Empty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IUnityContainer container, ICollection<Type> availableTypes)
|
||||
public void Configure(IServiceCollection services, ICollection<Type> availableTypes)
|
||||
{
|
||||
container.RegisterType<IFileManager, FileManager>(new SingletonLifetimeManager());
|
||||
container.RegisterType<ITranscoder, Transcoder>(new SingletonLifetimeManager());
|
||||
container.RegisterType<IThumbnailsManager, ThumbnailsManager>(new SingletonLifetimeManager());
|
||||
container.RegisterType<IProviderManager, ProviderManager>(new SingletonLifetimeManager());
|
||||
container.RegisterType<ITaskManager, TaskManager>(new SingletonLifetimeManager());
|
||||
services.AddSingleton<IFileManager, FileManager>();
|
||||
services.AddSingleton<ITranscoder, Transcoder>();
|
||||
services.AddSingleton<IThumbnailsManager, ThumbnailsManager>();
|
||||
services.AddSingleton<IProviderManager, ProviderManager>();
|
||||
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))
|
||||
{
|
||||
container.RegisterRepository<ILibraryRepository, LibraryRepository>();
|
||||
container.RegisterRepository<ILibraryItemRepository, LibraryItemRepository>();
|
||||
container.RegisterRepository<ICollectionRepository, CollectionRepository>();
|
||||
container.RegisterRepository<IShowRepository, ShowRepository>();
|
||||
container.RegisterRepository<ISeasonRepository, SeasonRepository>();
|
||||
container.RegisterRepository<IEpisodeRepository, EpisodeRepository>();
|
||||
container.RegisterRepository<ITrackRepository, TrackRepository>();
|
||||
container.RegisterRepository<IPeopleRepository, PeopleRepository>();
|
||||
container.RegisterRepository<IStudioRepository, StudioRepository>();
|
||||
container.RegisterRepository<IGenreRepository, GenreRepository>();
|
||||
container.RegisterRepository<IProviderRepository, ProviderRepository>();
|
||||
services.AddRepository<ILibraryRepository, LibraryRepository>();
|
||||
services.AddRepository<ILibraryItemRepository, LibraryItemRepository>();
|
||||
services.AddRepository<ICollectionRepository, CollectionRepository>();
|
||||
services.AddRepository<IShowRepository, ShowRepository>();
|
||||
services.AddRepository<ISeasonRepository, SeasonRepository>();
|
||||
services.AddRepository<IEpisodeRepository, EpisodeRepository>();
|
||||
services.AddRepository<ITrackRepository, TrackRepository>();
|
||||
services.AddRepository<IPeopleRepository, PeopleRepository>();
|
||||
services.AddRepository<IStudioRepository, StudioRepository>();
|
||||
services.AddRepository<IGenreRepository, GenreRepository>();
|
||||
services.AddRepository<IProviderRepository, ProviderRepository>();
|
||||
}
|
||||
|
||||
container.RegisterTask<Crawler>();
|
||||
services.AddTask<Crawler>();
|
||||
}
|
||||
}
|
||||
}
|
@ -47,8 +47,6 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.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>
|
||||
|
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.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.UnityExtensions;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.StaticWebAssets;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Unity;
|
||||
using Unity.Microsoft.DependencyInjection;
|
||||
|
||||
namespace Kyoo
|
||||
{
|
||||
/// <summary>
|
||||
@ -80,9 +76,6 @@ namespace Kyoo
|
||||
/// <returns>A new web host instance</returns>
|
||||
private static IWebHostBuilder CreateWebHostBuilder(string[] args)
|
||||
{
|
||||
UnityContainer container = new();
|
||||
container.EnableDebugDiagnostic();
|
||||
|
||||
return new WebHostBuilder()
|
||||
.UseContentRoot(AppDomain.CurrentDomain.BaseDirectory)
|
||||
.UseConfiguration(SetupConfig(new ConfigurationBuilder(), args).Build())
|
||||
@ -100,8 +93,6 @@ namespace Kyoo
|
||||
if (context.HostingEnvironment.IsDevelopment())
|
||||
StaticWebAssetsLoader.UseStaticWebAssets(context.HostingEnvironment, context.Configuration);
|
||||
})
|
||||
// .UseUnityProvider(container)
|
||||
.UseUnityServiceProvider(container)
|
||||
.ConfigureServices(x => x.AddRouting())
|
||||
.UseKestrel(options => { options.AddServerHeader = false; })
|
||||
.UseIIS()
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.SpaServices.AngularCli;
|
||||
@ -10,8 +11,6 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Unity;
|
||||
using Unity.Lifetime;
|
||||
|
||||
namespace Kyoo
|
||||
{
|
||||
@ -20,16 +19,38 @@ namespace Kyoo
|
||||
/// </summary>
|
||||
public class Startup
|
||||
{
|
||||
/// <summary>
|
||||
/// The configuration context
|
||||
/// </summary>
|
||||
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;
|
||||
_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)
|
||||
{
|
||||
string publicUrl = _configuration.GetValue<string>("public_url");
|
||||
@ -64,22 +85,17 @@ namespace Kyoo
|
||||
// });
|
||||
// services.AddAuthentication()
|
||||
|
||||
|
||||
// container.Resolve<IConfiguration>();
|
||||
|
||||
services.AddSingleton<ITaskManager, TaskManager>();
|
||||
services.AddHostedService(x => x.GetService<ITaskManager>() as TaskManager);
|
||||
services.AddSingleton(_plugins);
|
||||
services.AddTransient(typeof(Lazy<>), typeof(LazyDi<>));
|
||||
_plugins.ConfigureServices(services);
|
||||
}
|
||||
|
||||
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())
|
||||
app.UseDeveloperExceptionPage();
|
||||
@ -124,9 +140,7 @@ namespace Kyoo
|
||||
spa.UseAngularCliServer("start");
|
||||
});
|
||||
|
||||
IPluginManager pluginManager = container.Resolve<IPluginManager>();
|
||||
foreach (IPlugin plugin in pluginManager.GetAllPlugins())
|
||||
plugin.ConfigureAspNet(app);
|
||||
_plugins.ConfigureAspnet(app);
|
||||
|
||||
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