mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-12-22 08:45:23 +03:00
Allow custom plugin provided database providers to be loaded (#14171)
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Jellyfin.Database.Implementations;
|
||||
using Jellyfin.Database.Implementations.DbConfiguration;
|
||||
@@ -42,6 +44,28 @@ public static class ServiceCollectionExtensions
|
||||
return items;
|
||||
}
|
||||
|
||||
private static JellyfinDbProviderFactory? LoadDatabasePlugin(CustomDatabaseOptions customProviderOptions, IApplicationPaths applicationPaths)
|
||||
{
|
||||
var plugin = Directory.EnumerateDirectories(applicationPaths.PluginsPath)
|
||||
.Where(e => Path.GetFileName(e)!.StartsWith(customProviderOptions.PluginName, StringComparison.OrdinalIgnoreCase))
|
||||
.Order()
|
||||
.FirstOrDefault()
|
||||
?? throw new InvalidOperationException($"The requested custom database plugin with the name '{customProviderOptions.PluginName}' could not been found in '{applicationPaths.PluginsPath}'");
|
||||
|
||||
var dbProviderAssembly = Path.Combine(plugin, Path.ChangeExtension(customProviderOptions.PluginAssembly, "dll"));
|
||||
if (!File.Exists(dbProviderAssembly))
|
||||
{
|
||||
throw new InvalidOperationException($"Could not find the requested assembly at '{dbProviderAssembly}'");
|
||||
}
|
||||
|
||||
// we have to load the assembly without proxy to ensure maximum performance for this.
|
||||
var assembly = Assembly.LoadFrom(dbProviderAssembly);
|
||||
var dbProviderType = assembly.GetExportedTypes().FirstOrDefault(f => f.IsAssignableTo(typeof(IJellyfinDatabaseProvider)))
|
||||
?? throw new InvalidOperationException($"Could not find any type implementing the '{nameof(IJellyfinDatabaseProvider)}' interface.");
|
||||
|
||||
return (services) => (IJellyfinDatabaseProvider)ActivatorUtilities.CreateInstance(services, dbProviderType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="IDbContextFactory{TContext}"/> interface to the service collection with second level caching enabled.
|
||||
/// </summary>
|
||||
@@ -55,7 +79,6 @@ public static class ServiceCollectionExtensions
|
||||
IConfiguration configuration)
|
||||
{
|
||||
var efCoreConfiguration = configurationManager.GetConfiguration<DatabaseConfigurationOptions>("database");
|
||||
var providers = GetSupportedDbProviders();
|
||||
JellyfinDbProviderFactory? providerFactory = null;
|
||||
|
||||
if (efCoreConfiguration?.DatabaseType is null)
|
||||
@@ -80,9 +103,22 @@ public static class ServiceCollectionExtensions
|
||||
}
|
||||
}
|
||||
|
||||
if (!providers.TryGetValue(efCoreConfiguration.DatabaseType.ToUpperInvariant(), out providerFactory!))
|
||||
if (efCoreConfiguration.DatabaseType.Equals("PLUGIN_PROVIDER", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
throw new InvalidOperationException($"Jellyfin cannot find the database provider of type '{efCoreConfiguration.DatabaseType}'. Supported types are {string.Join(", ", providers.Keys)}");
|
||||
if (efCoreConfiguration.CustomProviderOptions is null)
|
||||
{
|
||||
throw new InvalidOperationException("The custom database provider must declare the custom provider options to work");
|
||||
}
|
||||
|
||||
providerFactory = LoadDatabasePlugin(efCoreConfiguration.CustomProviderOptions, configurationManager.ApplicationPaths);
|
||||
}
|
||||
else
|
||||
{
|
||||
var providers = GetSupportedDbProviders();
|
||||
if (!providers.TryGetValue(efCoreConfiguration.DatabaseType.ToUpperInvariant(), out providerFactory!))
|
||||
{
|
||||
throw new InvalidOperationException($"Jellyfin cannot find the database provider of type '{efCoreConfiguration.DatabaseType}'. Supported types are {string.Join(", ", providers.Keys)}");
|
||||
}
|
||||
}
|
||||
|
||||
serviceCollection.AddSingleton<IJellyfinDatabaseProvider>(providerFactory!);
|
||||
|
||||
Reference in New Issue
Block a user