浏览代码

Fixed DbContext usage on Provider

JPVenson 5 月之前
父节点
当前提交
9d1c4ea169

+ 5 - 1
Emby.Server.Implementations/ApplicationHost.cs

@@ -575,7 +575,11 @@ namespace Emby.Server.Implementations
         /// <returns>A task representing the service initialization operation.</returns>
         public async Task InitializeServices()
         {
-            var jellyfinDb = await Resolve<IDbContextFactory<JellyfinDbContext>>().CreateDbContextAsync().ConfigureAwait(false);
+            var factory = Resolve<IDbContextFactory<JellyfinDbContext>>();
+            var provider = Resolve<IJellyfinDatabaseProvider>();
+            provider.DbContextFactory = factory;
+
+            var jellyfinDb = await factory.CreateDbContextAsync().ConfigureAwait(false);
             await using (jellyfinDb.ConfigureAwait(false))
             {
                 if ((await jellyfinDb.Database.GetPendingMigrationsAsync().ConfigureAwait(false)).Any())

+ 5 - 0
Jellyfin.Database/Jellyfin.Database.Implementations/IJellyfinDatabaseProvider.cs

@@ -10,6 +10,11 @@ namespace Jellyfin.Server.Implementations;
 /// </summary>
 public interface IJellyfinDatabaseProvider : IAsyncDisposable
 {
+    /// <summary>
+    /// Gets or Sets the Database Factory when initialisaition is done.
+    /// </summary>
+    IDbContextFactory<JellyfinDbContext>? DbContextFactory { get; set; }
+
     /// <summary>
     /// Initialises jellyfins EFCore database access.
     /// </summary>

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Providers.SqLite/Jellyfin.Database.Providers.SqLite.csproj

@@ -45,7 +45,7 @@
     <ProjectReference Include="..\..\Jellyfin.Data\Jellyfin.Data.csproj" />
     <ProjectReference Include="..\..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
     <ProjectReference Include="..\..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
-    <ProjectReference Include="..\..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" />
+    <!-- <ProjectReference Include="..\..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" /> -->
   </ItemGroup>
 
 </Project>

+ 1 - 1
Jellyfin.Database/Jellyfin.Database.Providers.SqLite/Migrations/DesignTimeJellyfinDbFactory.cs

@@ -19,7 +19,7 @@ namespace Jellyfin.Server.Implementations.Migrations
             return new JellyfinDbContext(
                 optionsBuilder.Options,
                 NullLogger<JellyfinDbContext>.Instance,
-                new SqliteDatabaseProvider(null!, null!, NullLogger<SqliteDatabaseProvider>.Instance));
+                new SqliteDatabaseProvider(null!, NullLogger<SqliteDatabaseProvider>.Instance));
         }
     }
 }

+ 0 - 0
Jellyfin.Server.Implementations/ModelBuilderExtensions.cs → Jellyfin.Database/Jellyfin.Database.Providers.SqLite/ModelBuilderExtensions.cs


+ 6 - 6
Jellyfin.Database/Jellyfin.Database.Providers.SqLite/SqliteDatabaseProvider.cs

@@ -10,6 +10,7 @@ namespace Jellyfin.Database.Providers.SqLite;
 /// <summary>
 /// Configures jellyfin to use an SqLite database.
 /// </summary>
+[JellyfinDatabaseProviderKey("Jellyfin-SqLite")]
 public sealed class SqliteDatabaseProvider : IJellyfinDatabaseProvider
 {
     private readonly IApplicationPaths _applicationPaths;
@@ -18,17 +19,16 @@ public sealed class SqliteDatabaseProvider : IJellyfinDatabaseProvider
     /// <summary>
     /// Initializes a new instance of the <see cref="SqliteDatabaseProvider"/> class.
     /// </summary>
-    /// <param name="dbContextFactory">The Db context to interact with the database.</param>
     /// <param name="applicationPaths">Service to construct the fallback when the old data path configuration is used.</param>
     /// <param name="logger">A logger.</param>
-    public SqliteDatabaseProvider(IDbContextFactory<JellyfinDbContext> dbContextFactory, IApplicationPaths applicationPaths, ILogger<SqliteDatabaseProvider> logger)
+    public SqliteDatabaseProvider(IApplicationPaths applicationPaths, ILogger<SqliteDatabaseProvider> logger)
     {
-        DbContextFactory = dbContextFactory;
         _applicationPaths = applicationPaths;
         _logger = logger;
     }
 
-    private IDbContextFactory<JellyfinDbContext> DbContextFactory { get; }
+    /// <inheritdoc/>
+    public IDbContextFactory<JellyfinDbContext>? DbContextFactory { get; set; }
 
     /// <inheritdoc/>
     public void Initialise(DbContextOptionsBuilder options)
@@ -41,7 +41,7 @@ public sealed class SqliteDatabaseProvider : IJellyfinDatabaseProvider
     /// <inheritdoc/>
     public async Task RunScheduledOptimisation(CancellationToken cancellationToken)
     {
-        var context = await DbContextFactory.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
+        var context = await DbContextFactory!.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
         await using (context.ConfigureAwait(false))
         {
             if (context.Database.IsSqlite())
@@ -67,7 +67,7 @@ public sealed class SqliteDatabaseProvider : IJellyfinDatabaseProvider
     public async ValueTask DisposeAsync()
     {
         // Run before disposing the application
-        var context = await DbContextFactory.CreateDbContextAsync().ConfigureAwait(false);
+        var context = await DbContextFactory!.CreateDbContextAsync().ConfigureAwait(false);
         await using (context.ConfigureAwait(false))
         {
             await context.Database.ExecuteSqlRawAsync("PRAGMA optimize").ConfigureAwait(false);

+ 0 - 0
Jellyfin.Server.Implementations/ValueConverters/DateTimeKindValueConverter.cs → Jellyfin.Database/Jellyfin.Database.Providers.SqLite/ValueConverters/DateTimeKindValueConverter.cs


+ 11 - 8
Jellyfin.Server.Implementations/Extensions/ServiceCollectionExtensions.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Reflection;
+using Jellyfin.Database.Providers.SqLite;
 using Jellyfin.Server.Implementations.DatabaseConfiguration;
 using MediaBrowser.Common.Configuration;
 using MediaBrowser.Controller.Configuration;
@@ -17,14 +18,15 @@ namespace Jellyfin.Server.Implementations.Extensions;
 /// </summary>
 public static class ServiceCollectionExtensions
 {
+    private static IEnumerable<Type> DatabaseProviderTypes()
+    {
+        yield return typeof(SqliteDatabaseProvider);
+    }
+
     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)))
+        foreach (var providerType in DatabaseProviderTypes())
         {
             var keyAttribute = providerType.GetCustomAttribute<JellyfinDatabaseProviderKeyAttribute>();
             if (keyAttribute is null || string.IsNullOrWhiteSpace(keyAttribute.DatabaseProviderKey))
@@ -51,15 +53,16 @@ public static class ServiceCollectionExtensions
         var providers = GetSupportedDbProviders();
         JellyfinDbProviderFactory? providerFactory = null;
 
-        if (efCoreConfiguration is null)
+        if (efCoreConfiguration?.DatabaseType is null)
         {
             // when nothing is setup via new Database configuration, fallback to SqLite with default settings.
             efCoreConfiguration = new DatabaseConfigurationOptions()
             {
-                DatabaseType = "SqLite",
+                DatabaseType = "Jellyfin-SqLite",
             };
         }
-        else if (!providers.TryGetValue(efCoreConfiguration.DatabaseType, out providerFactory!))
+
+        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)}");
         }

+ 1 - 0
Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj

@@ -36,6 +36,7 @@
     <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" />
     <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" />
     <ProjectReference Include="..\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
+    <ProjectReference Include="..\Jellyfin.Database\Jellyfin.Database.Providers.SqLite\Jellyfin.Database.Providers.SqLite.csproj" />
   </ItemGroup>
 
 </Project>

+ 5 - 1
Jellyfin.Server/CoreAppHost.cs

@@ -11,6 +11,7 @@ using Jellyfin.Server.Implementations;
 using Jellyfin.Server.Implementations.Activity;
 using Jellyfin.Server.Implementations.Devices;
 using Jellyfin.Server.Implementations.Events;
+using Jellyfin.Server.Implementations.Extensions;
 using Jellyfin.Server.Implementations.Security;
 using Jellyfin.Server.Implementations.Trickplay;
 using Jellyfin.Server.Implementations.Users;
@@ -116,9 +117,12 @@ namespace Jellyfin.Server
             // Jellyfin.Server
             yield return typeof(CoreAppHost).Assembly;
 
-            // Jellyfin.Server.Implementations
+            // Jellyfin.Database.Implementations
             yield return typeof(JellyfinDbContext).Assembly;
 
+            // Jellyfin.Server.Implementations
+            yield return typeof(ServiceCollectionExtensions).Assembly;
+
             // Jellyfin.LiveTv
             yield return typeof(LiveTvManager).Assembly;
         }