2024-08-30 15:29:48 +02:00
using System ;
2025-01-26 20:45:28 +00:00
using System.Collections.Generic ;
2022-10-21 11:55:32 +02:00
using System.IO ;
2025-01-26 20:45:28 +00:00
using System.Linq ;
using System.Reflection ;
using Jellyfin.Server.Implementations.DatabaseConfiguration ;
2022-10-21 11:55:32 +02:00
using MediaBrowser.Common.Configuration ;
2025-01-26 20:45:28 +00:00
using MediaBrowser.Controller.Configuration ;
2022-10-21 11:55:32 +02:00
using Microsoft.EntityFrameworkCore ;
using Microsoft.Extensions.DependencyInjection ;
2025-01-26 20:45:28 +00:00
using JellyfinDbProviderFactory = System . Func < System . IServiceProvider , Jellyfin . Server . Implementations . IJellyfinDatabaseProvider > ;
2022-10-21 11:55:32 +02:00
namespace Jellyfin.Server.Implementations.Extensions ;
/// <summary>
/// Extensions for the <see cref="IServiceCollection"/> interface.
/// </summary>
public static class ServiceCollectionExtensions
{
2025-01-26 20:45:28 +00:00
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 ;
}
2022-10-21 11:55:32 +02:00
/// <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>
2025-01-26 20:45:28 +00:00
/// <param name="configurationManager">The server configuration manager.</param>
2022-10-21 11:55:32 +02:00
/// <returns>The updated service collection.</returns>
2025-01-26 20:45:28 +00:00
public static IServiceCollection AddJellyfinDbContext ( this IServiceCollection serviceCollection , IServerConfigurationManager configurationManager )
2022-10-21 11:55:32 +02:00
{
2025-01-26 20:45:28 +00:00
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 ! ) ;
2023-01-16 12:14:44 -05:00
serviceCollection . AddPooledDbContextFactory < JellyfinDbContext > ( ( serviceProvider , opt ) = >
2022-10-21 11:55:32 +02:00
{
2025-01-26 20:45:28 +00:00
var provider = serviceProvider . GetRequiredService < IJellyfinDatabaseProvider > ( ) ;
provider . Initialise ( opt ) ;
2022-10-21 11:55:32 +02:00
} ) ;
return serviceCollection ;
}
}