diff options
Diffstat (limited to 'Jellyfin.Server.Implementations/Extensions/ServiceCollectionExtensions.cs')
| -rw-r--r-- | Jellyfin.Server.Implementations/Extensions/ServiceCollectionExtensions.cs | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/Jellyfin.Server.Implementations/Extensions/ServiceCollectionExtensions.cs b/Jellyfin.Server.Implementations/Extensions/ServiceCollectionExtensions.cs index 7eee26059..e48f4ce10 100644 --- a/Jellyfin.Server.Implementations/Extensions/ServiceCollectionExtensions.cs +++ b/Jellyfin.Server.Implementations/Extensions/ServiceCollectionExtensions.cs @@ -1,8 +1,14 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; +using System.Reflection; +using Jellyfin.Server.Implementations.DatabaseConfiguration; using MediaBrowser.Common.Configuration; +using MediaBrowser.Controller.Configuration; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; +using JellyfinDbProviderFactory = System.Func<System.IServiceProvider, Jellyfin.Server.Implementations.IJellyfinDatabaseProvider>; namespace Jellyfin.Server.Implementations.Extensions; @@ -11,17 +17,59 @@ namespace Jellyfin.Server.Implementations.Extensions; /// </summary> public static class ServiceCollectionExtensions { + private static IDictionary<string, JellyfinDbProviderFactory> GetSupportedDbProviders() + { + var items = new Dictionary<string, JellyfinDbProviderFactory>(); + foreach (var providerType in AppDomain + .CurrentDomain + .GetAssemblies() + .SelectMany(f => f.GetTypes()) + .Where(e => e.IsClass && typeof(IJellyfinDatabaseProvider).IsAssignableFrom(e))) + { + var keyAttribute = providerType.GetCustomAttribute<JellyfinDatabaseProviderKeyAttribute>(); + if (keyAttribute is null || string.IsNullOrWhiteSpace(keyAttribute.DatabaseProviderKey)) + { + continue; + } + + var provider = providerType; + items[keyAttribute.DatabaseProviderKey] = (services) => (IJellyfinDatabaseProvider)ActivatorUtilities.CreateInstance(services, providerType); + } + + return items; + } + /// <summary> /// Adds the <see cref="IDbContextFactory{TContext}"/> interface to the service collection with second level caching enabled. /// </summary> /// <param name="serviceCollection">An instance of the <see cref="IServiceCollection"/> interface.</param> + /// <param name="configurationManager">The server configuration manager.</param> /// <returns>The updated service collection.</returns> - public static IServiceCollection AddJellyfinDbContext(this IServiceCollection serviceCollection) + public static IServiceCollection AddJellyfinDbContext(this IServiceCollection serviceCollection, IServerConfigurationManager configurationManager) { + var efCoreConfiguration = configurationManager.GetConfiguration<DatabaseConfigurationOptions>("database"); + var providers = GetSupportedDbProviders(); + JellyfinDbProviderFactory? providerFactory = null; + + if (efCoreConfiguration is null) + { + // when nothing is setup via new Database configuration, fallback to SqLite with default settings. + efCoreConfiguration = new DatabaseConfigurationOptions() + { + DatabaseType = "SqLite", + }; + } + else if (!providers.TryGetValue(efCoreConfiguration.DatabaseType, 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!); + serviceCollection.AddPooledDbContextFactory<JellyfinDbContext>((serviceProvider, opt) => { - var applicationPaths = serviceProvider.GetRequiredService<IApplicationPaths>(); - opt.UseSqlite($"Filename={Path.Combine(applicationPaths.DataPath, "jellyfin.db")};Pooling=false"); + var provider = serviceProvider.GetRequiredService<IJellyfinDatabaseProvider>(); + provider.Initialise(opt); }); return serviceCollection; |
