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 @@ +