diff --git a/Kyoo.Authentication/AuthenticationModule.cs b/Kyoo.Authentication/AuthenticationModule.cs
index 1e9dcd01..8e3ea475 100644
--- a/Kyoo.Authentication/AuthenticationModule.cs
+++ b/Kyoo.Authentication/AuthenticationModule.cs
@@ -37,20 +37,8 @@ namespace Kyoo.Authentication
///
public string Description => "Enable OpenID authentication for Kyoo.";
-
- ///
- public ICollection Provides => ArraySegment.Empty;
-
- ///
- public ICollection ConditionalProvides => ArraySegment.Empty;
-
- ///
- public ICollection Requires => new []
- {
- typeof(IUserRepository)
- };
-
-
+
+
///
/// The configuration to use.
///
@@ -88,7 +76,7 @@ namespace Kyoo.Authentication
}
///
- public void Configure(IServiceCollection services, ICollection availableTypes)
+ public void Configure(IServiceCollection services)
{
string publicUrl = _configuration.GetPublicUrl();
diff --git a/Kyoo.Common/Controllers/IPlugin.cs b/Kyoo.Common/Controllers/IPlugin.cs
index ea072c39..06670ff3 100644
--- a/Kyoo.Common/Controllers/IPlugin.cs
+++ b/Kyoo.Common/Controllers/IPlugin.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using Autofac;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Builder;
@@ -34,29 +32,15 @@ namespace Kyoo.Controllers
string Description { get; }
///
- /// A list of services that are provided by this service. This allow other plugins to declare dependencies
+ /// true if the plugin should be enabled, false otherwise.
+ /// If a plugin is not enabled, no configure method will be called.
+ /// This allow one to enable a plugin if a specific configuration value is set or if the environment contains
+ /// the right settings.
///
///
- /// You should put the type's interface that will be register in configure.
+ /// By default, a plugin is always enabled. This method can be overriden to change this behavior.
///
- ICollection Provides { get; }
-
- ///
- /// A list of types that will be provided only if a condition is met. The condition can be an arbitrary method or
- /// a condition based on other type availability. For more information, see .
- ///
- ICollection ConditionalProvides { get; }
-
- ///
- /// A list of services that are required by this plugin.
- /// You can put services that you provide conditionally here if you want.
- /// Kyoo will warn the user that this plugin can't be loaded if a required service is not found.
- ///
- ///
- /// Put here the most complete type that are needed for your plugin to work. If you need a LibraryManager,
- /// put typeof(ILibraryManager).
- ///
- ICollection Requires { get; }
+ virtual bool Enabled => true;
///
/// A configure method that will be run on plugin's startup.
@@ -69,14 +53,11 @@ namespace Kyoo.Controllers
///
/// A configure method that will be run on plugin's startup.
+ /// This is available for libraries that build upon a , for more precise
+ /// configuration use .
///
/// A service container to register new services.
- /// The list of types that are available for this instance. This can be used
- /// for conditional type. See
- /// or >
- /// You can't simply check on the service collection because some dependencies might be registered after your plugin.
- ///
- void Configure(IServiceCollection services, ICollection availableTypes)
+ void Configure(IServiceCollection services)
{
// Skipped
}
@@ -105,143 +86,4 @@ namespace Kyoo.Controllers
// Skipped
}
}
-
- ///
- /// A type that will only be provided if a special condition is met. To check that your condition is met,
- /// you can check the class.
- ///
- public class ConditionalProvide : Tuple
- {
- ///
- /// Get the type that may be provided
- ///
- public Type Type => Item1;
-
- ///
- /// Get the condition.
- ///
- public ProviderCondition Condition => Item2;
-
- ///
- /// Create a from a type and a condition.
- ///
- /// The type to provide
- /// The condition
- public ConditionalProvide(Type type, ProviderCondition condition)
- : base(type, condition)
- { }
-
- ///
- /// Create a from a tuple of (Type, ProviderCondition).
- ///
- /// The tuple to convert
- public ConditionalProvide((Type type, ProviderCondition condition) tuple)
- : base(tuple.type, tuple.condition)
- { }
-
- ///
- /// Implicitly convert a tuple to a .
- ///
- /// The tuple to convert
- /// A new based on the given tuple.
- public static implicit operator ConditionalProvide((Type, Type) tuple) => new (tuple);
- }
-
- ///
- /// A condition for a conditional type.
- ///
- public class ProviderCondition
- {
- ///
- /// The condition as a method. If true is returned, the type will be provided.
- ///
- public Func Condition { get; } = () => true;
- ///
- /// The list of types that this method needs.
- ///
- public ICollection Needed { get; } = ArraySegment.Empty;
-
-
- ///
- /// Create a new from a raw function.
- ///
- /// The predicate that will be used as condition
- public ProviderCondition(Func condition)
- {
- Condition = condition;
- }
-
- ///
- /// Create a new from a type. This allow you to inform that a type will
- /// only be available if a dependency is met.
- ///
- /// The type that you need
- public ProviderCondition(Type needed)
- {
- Needed = new[] {needed};
- }
-
- ///
- /// Create a new from a list of type. This allow you to inform that a type will
- /// only be available if a list of dependencies are met.
- ///
- /// The types that you need
- public ProviderCondition(ICollection needed)
- {
- Needed = needed;
- }
-
- ///
- /// Create a new with a list of types as dependencies and a predicate
- /// for arbitrary conditions.
- ///
- /// The list of dependencies
- /// An arbitrary condition
- public ProviderCondition(ICollection needed, Func condition)
- {
- Needed = needed;
- Condition = condition;
- }
-
-
- ///
- /// Implicitly convert a type to a .
- ///
- /// The type dependency
- /// A that will return true if the given type is available.
- public static implicit operator ProviderCondition(Type type) => new(type);
-
- ///
- /// Implicitly convert a list of type to a .
- ///
- /// The list of type dependencies
- /// A that will return true if the given types are available.
- public static implicit operator ProviderCondition(Type[] types) => new(types);
-
- ///
- public static implicit operator ProviderCondition(List types) => new(types);
-
-
- ///
- /// Check if a type is available.
- ///
- /// The type to check
- /// The list of types
- /// True if the dependency is met, false otherwise
- public static bool Has(Type needed, ICollection available)
- {
- return available.Contains(needed);
- }
-
- ///
- /// Check if a list of type are available.
- ///
- /// The list of types to check
- /// The list of types
- /// True if the dependencies are met, false otherwise
- public static bool Has(ICollection needed, ICollection available)
- {
- return needed.All(x => Has(x, available));
- }
- }
}
\ No newline at end of file
diff --git a/Kyoo.Postgresql/PostgresModule.cs b/Kyoo.Postgresql/PostgresModule.cs
index 6b84bd93..b05c1ab7 100644
--- a/Kyoo.Postgresql/PostgresModule.cs
+++ b/Kyoo.Postgresql/PostgresModule.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using Kyoo.Controllers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
@@ -24,19 +23,6 @@ namespace Kyoo.Postgresql
///
public string Description => "A database context for postgresql.";
- ///
- public ICollection Provides => new[]
- {
- typeof(DatabaseContext)
- };
-
- ///
- public ICollection ConditionalProvides => ArraySegment.Empty;
-
- ///
- public ICollection Requires => ArraySegment.Empty;
-
-
///
/// The configuration to use. The database connection string is pulled from it.
///
@@ -59,7 +45,7 @@ namespace Kyoo.Postgresql
}
///
- public void Configure(IServiceCollection services, ICollection availableTypes)
+ public void Configure(IServiceCollection services)
{
services.AddDbContext(x =>
{
diff --git a/Kyoo.SqLite/SqLiteModule.cs b/Kyoo.SqLite/SqLiteModule.cs
index 96c29836..0aa378d7 100644
--- a/Kyoo.SqLite/SqLiteModule.cs
+++ b/Kyoo.SqLite/SqLiteModule.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using Kyoo.Controllers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
@@ -23,19 +22,7 @@ namespace Kyoo.SqLite
///
public string Description => "A database context for sqlite.";
- ///
- public ICollection Provides => new[]
- {
- typeof(DatabaseContext)
- };
-
- ///
- public ICollection ConditionalProvides => ArraySegment.Empty;
-
- ///
- public ICollection Requires => ArraySegment.Empty;
-
-
+
///
/// The configuration to use. The database connection string is pulled from it.
///
@@ -59,7 +46,7 @@ namespace Kyoo.SqLite
///
- public void Configure(IServiceCollection services, ICollection availableTypes)
+ public void Configure(IServiceCollection services)
{
services.AddDbContext(x =>
{
diff --git a/Kyoo.TheMovieDb/PluginTmdb.cs b/Kyoo.TheMovieDb/PluginTmdb.cs
index aaf5aa9c..c1d6d494 100644
--- a/Kyoo.TheMovieDb/PluginTmdb.cs
+++ b/Kyoo.TheMovieDb/PluginTmdb.cs
@@ -1,5 +1,3 @@
-using System;
-using System.Collections.Generic;
using Autofac;
using Kyoo.Controllers;
using Kyoo.Models.Attributes;
@@ -23,20 +21,8 @@ namespace Kyoo.TheMovieDb
///
public string Description => "A metadata provider for TheMovieDB.";
-
- ///
- public ICollection Provides => new []
- {
- typeof(IMetadataProvider)
- };
-
- ///
- public ICollection ConditionalProvides => ArraySegment.Empty;
-
- ///
- public ICollection Requires => ArraySegment.Empty;
-
-
+
+
///
/// The configuration to use.
///
@@ -65,7 +51,7 @@ namespace Kyoo.TheMovieDb
}
///
- public void Configure(IServiceCollection services, ICollection availableTypes)
+ public void Configure(IServiceCollection services)
{
services.Configure(_configuration.GetSection(TheMovieDbOptions.Path));
}
diff --git a/Kyoo.TheTvdb/PluginTvdb.cs b/Kyoo.TheTvdb/PluginTvdb.cs
index e0b697ea..74f9483d 100644
--- a/Kyoo.TheTvdb/PluginTvdb.cs
+++ b/Kyoo.TheTvdb/PluginTvdb.cs
@@ -1,5 +1,3 @@
-using System;
-using System.Collections.Generic;
using Autofac;
using Kyoo.Controllers;
using Kyoo.Models.Attributes;
@@ -24,20 +22,7 @@ namespace Kyoo.TheTvdb
///
public string Description => "A metadata provider for The TVDB.";
-
- ///
- public ICollection Provides => new []
- {
- typeof(IMetadataProvider)
- };
-
- ///
- public ICollection ConditionalProvides => ArraySegment.Empty;
-
- ///
- public ICollection Requires => ArraySegment.Empty;
-
-
+
///
/// The configuration to use.
///
@@ -67,7 +52,7 @@ namespace Kyoo.TheTvdb
}
///
- public void Configure(IServiceCollection services, ICollection availableTypes)
+ public void Configure(IServiceCollection services)
{
services.Configure(_configuration.GetSection(TvdbOption.Path));
}
diff --git a/Kyoo/Controllers/PluginManager.cs b/Kyoo/Controllers/PluginManager.cs
index 215b0c9b..4812883d 100644
--- a/Kyoo/Controllers/PluginManager.cs
+++ b/Kyoo/Controllers/PluginManager.cs
@@ -112,22 +112,11 @@ namespace Kyoo.Controllers
_logger.LogTrace("Loading new plugins...");
string[] pluginsPaths = Directory.GetFiles(pluginFolder, "*.dll", SearchOption.AllDirectories);
- plugins = plugins.Concat(pluginsPaths.SelectMany(LoadPlugin))
+ _plugins.AddRange(plugins
+ .Concat(pluginsPaths.SelectMany(LoadPlugin))
.GroupBy(x => x.Name)
.Select(x => x.First())
- .ToList();
-
- ICollection available = GetProvidedTypes(plugins);
- _plugins.AddRange(plugins.Where(plugin =>
- {
- Type missing = plugin.Requires.FirstOrDefault(x => available.All(y => !y.IsAssignableTo(x)));
- if (missing == null)
- return true;
-
- _logger.LogCritical("No {Dependency} available in Kyoo but the plugin {Plugin} requires it",
- missing.Name, plugin.Name);
- return false;
- }));
+ );
if (!_plugins.Any())
_logger.LogInformation("No plugin enabled");
@@ -138,7 +127,10 @@ namespace Kyoo.Controllers
///
public void LoadPlugins(params Type[] plugins)
{
- throw new NotImplementedException();
+ LoadPlugins(plugins
+ .Select(x => (IPlugin)ActivatorUtilities.CreateInstance(_provider, x))
+ .ToArray()
+ );
}
///
@@ -151,9 +143,8 @@ namespace Kyoo.Controllers
///
public void ConfigureServices(IServiceCollection services)
{
- ICollection available = GetProvidedTypes(_plugins);
foreach (IPlugin plugin in _plugins)
- plugin.Configure(services, available);
+ plugin.Configure(services);
}
///
@@ -168,53 +159,6 @@ namespace Kyoo.Controllers
}
}
- ///
- /// Get the list of types provided by the currently loaded plugins.
- ///
- /// The list of plugins that will be used as a plugin pool to get provided types.
- /// The list of types available.
- private ICollection GetProvidedTypes(ICollection plugins)
- {
- List available = plugins.SelectMany(x => x.Provides).ToList();
- List conditionals = plugins
- .SelectMany(x => x.ConditionalProvides)
- .Where(x => x.Condition.Condition())
- .ToList();
-
- bool IsAvailable(ConditionalProvide conditional, bool log = false)
- {
- if (!conditional.Condition.Condition())
- return false;
-
- ICollection needed = conditional.Condition.Needed
- .Where(y => !available.Contains(y))
- .ToList();
- // TODO handle circular dependencies, actually it might stack overflow.
- needed = needed.Where(x => !conditionals
- .Where(y => y.Type == x)
- .Any(y => IsAvailable(y)))
- .ToList();
- if (!needed.Any())
- return true;
- if (log && available.All(x => x != conditional.Type))
- {
- _logger.LogWarning("The type {Type} is not available, {Dependencies} could not be met",
- conditional.Type.Name,
- needed.Select(x => x.Name));
- }
- return false;
- }
-
- // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator
- foreach (ConditionalProvide conditional in conditionals)
- {
- if (IsAvailable(conditional, true))
- available.Add(conditional.Type);
- }
- return available;
- }
-
-
///
/// 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 51f4f94c..5fe9e977 100644
--- a/Kyoo/CoreModule.cs
+++ b/Kyoo/CoreModule.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.IO;
using Autofac;
using Autofac.Core;
@@ -31,53 +30,7 @@ namespace Kyoo
///
public string Description => "The core module containing default implementations.";
- ///
- public ICollection Provides => new[]
- {
- typeof(IFileSystem),
- typeof(ITranscoder),
- typeof(IThumbnailsManager),
- typeof(IMetadataProvider),
- typeof(ITaskManager),
- typeof(ILibraryManager),
- typeof(IIdentifier),
- typeof(AProviderComposite)
- };
- ///
- public ICollection ConditionalProvides => new ConditionalProvide[]
- {
- (typeof(ILibraryRepository), typeof(DatabaseContext)),
- (typeof(ILibraryItemRepository), typeof(DatabaseContext)),
- (typeof(ICollectionRepository), typeof(DatabaseContext)),
- (typeof(IShowRepository), typeof(DatabaseContext)),
- (typeof(ISeasonRepository), typeof(DatabaseContext)),
- (typeof(IEpisodeRepository), typeof(DatabaseContext)),
- (typeof(ITrackRepository), typeof(DatabaseContext)),
- (typeof(IPeopleRepository), typeof(DatabaseContext)),
- (typeof(IStudioRepository), typeof(DatabaseContext)),
- (typeof(IGenreRepository), typeof(DatabaseContext)),
- (typeof(IProviderRepository), typeof(DatabaseContext)),
- (typeof(IUserRepository), typeof(DatabaseContext))
- };
-
- ///
- public ICollection Requires => new []
- {
- typeof(ILibraryRepository),
- typeof(ILibraryItemRepository),
- typeof(ICollectionRepository),
- typeof(IShowRepository),
- typeof(ISeasonRepository),
- typeof(IEpisodeRepository),
- typeof(ITrackRepository),
- typeof(IPeopleRepository),
- typeof(IStudioRepository),
- typeof(IGenreRepository),
- typeof(IProviderRepository)
- };
-
-
///
/// The configuration to use.
///
@@ -142,7 +95,7 @@ namespace Kyoo
}
///
- public void Configure(IServiceCollection services, ICollection availableTypes)
+ public void Configure(IServiceCollection services)
{
string publicUrl = _configuration.GetPublicUrl();
diff --git a/Kyoo/PluginsStartup.cs b/Kyoo/PluginsStartup.cs
index e279cb57..a28d118c 100644
--- a/Kyoo/PluginsStartup.cs
+++ b/Kyoo/PluginsStartup.cs
@@ -43,7 +43,7 @@ namespace Kyoo
typeof(CoreModule),
typeof(AuthenticationModule),
typeof(PostgresModule),
- typeof(SqLiteModule),
+ // typeof(SqLiteModule),
typeof(PluginTvdb),
typeof(PluginTmdb)
);
diff --git a/Kyoo/Program.cs b/Kyoo/Program.cs
index 4e618efc..064cb6e7 100644
--- a/Kyoo/Program.cs
+++ b/Kyoo/Program.cs
@@ -1,10 +1,8 @@
using System;
-using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Threading.Tasks;
using Autofac.Extensions.DependencyInjection;
-using Kyoo.Controllers;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;