diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0998c2b312..3b6d7bfedf 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -59,6 +59,7 @@
+
diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs
index d5b6e93b8e..c308fe50ad 100644
--- a/Jellyfin.Server/CoreAppHost.cs
+++ b/Jellyfin.Server/CoreAppHost.cs
@@ -7,6 +7,7 @@ using Jellyfin.Api.WebSocketListeners;
using Jellyfin.Drawing;
using Jellyfin.Drawing.Skia;
using Jellyfin.LiveTv;
+using Jellyfin.Server.Helpers;
using Jellyfin.Server.Implementations;
using Jellyfin.Server.Implementations.Activity;
using Jellyfin.Server.Implementations.Devices;
@@ -26,10 +27,10 @@ using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Trickplay;
using MediaBrowser.Model.Activity;
-using MediaBrowser.Providers.Lyric;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
+using Scrutor;
namespace Jellyfin.Server
{
@@ -74,15 +75,29 @@ namespace Jellyfin.Server
Logger.LogWarning("Skia not available. Will fallback to {ImageEncoder}.", nameof(NullImageEncoder));
}
+ serviceCollection.Scan(scan =>
+ {
+ var selector = scan.FromAssemblies(AppDomain.CurrentDomain.GetAssemblies());
+ AsSingleton(selector);
+ AsSingleton(selector);
+ AsSingleton(selector);
+ AsSingleton(selector);
+
+ return;
+
+ static void AsSingleton(IImplementationTypeSelector selector)
+ => selector.AddClasses(c => c.AssignableTo())
+ .UsingRegistrationStrategy(DistinctRegistrationStrategy.Instance)
+ .AsImplementedInterfaces()
+ .WithSingletonLifetime();
+ });
+
serviceCollection.AddEventServices();
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
- serviceCollection.AddSingleton();
- serviceCollection.AddSingleton();
- serviceCollection.AddSingleton();
serviceCollection.AddScoped();
serviceCollection.AddSingleton();
serviceCollection.AddSingleton();
@@ -97,16 +112,6 @@ namespace Jellyfin.Server
serviceCollection.AddScoped();
- foreach (var type in GetExportTypes())
- {
- serviceCollection.AddSingleton(typeof(ILyricProvider), type);
- }
-
- foreach (var type in GetExportTypes())
- {
- serviceCollection.AddSingleton(typeof(ILyricParser), type);
- }
-
base.RegisterServices(serviceCollection);
}
diff --git a/Jellyfin.Server/Helpers/DistinctRegistrationStrategy.cs b/Jellyfin.Server/Helpers/DistinctRegistrationStrategy.cs
new file mode 100644
index 0000000000..67ec1e52ae
--- /dev/null
+++ b/Jellyfin.Server/Helpers/DistinctRegistrationStrategy.cs
@@ -0,0 +1,27 @@
+using System.Linq;
+using Microsoft.Extensions.DependencyInjection;
+using Scrutor;
+
+namespace Jellyfin.Server.Helpers;
+
+///
+/// Skip registering the descriptor if it exists.
+///
+public class DistinctRegistrationStrategy : RegistrationStrategy
+{
+ ///
+ /// The distinct registration strategy instance.
+ ///
+ public static readonly DistinctRegistrationStrategy Instance = new();
+
+ ///
+ public override void Apply(IServiceCollection services, ServiceDescriptor descriptor)
+ {
+ if (services.Any(service => service.ServiceType == descriptor.ServiceType && service.ImplementationType == descriptor.ImplementationType))
+ {
+ return;
+ }
+
+ services.Add(descriptor);
+ }
+}
diff --git a/Jellyfin.Server/Jellyfin.Server.csproj b/Jellyfin.Server/Jellyfin.Server.csproj
index e18212908e..38dc95d3ae 100644
--- a/Jellyfin.Server/Jellyfin.Server.csproj
+++ b/Jellyfin.Server/Jellyfin.Server.csproj
@@ -50,6 +50,7 @@
+