fix: resolve circular dependency in music metadata service resolution by defining IConcreteMetadataService

This commit is contained in:
joshpatra committed 2026-07-08 09:41:59 -04:00
1 parent fa69e7de65
commit a60e921646
9 files changed
+24 -17

No files matched your search

+4 -4
View File
@@ -574,10 +574,10 @@ else
builder.Services.AddSingleton<QobuzBundleService>();
// 1. Concrete Metadata Services
builder.Services.AddSingleton<IMusicMetadataService, DeezerMetadataService>();
builder.Services.AddSingleton<IMusicMetadataService, QobuzMetadataService>();
builder.Services.AddSingleton<IMusicMetadataService, AppleMusicMetadataService>();
builder.Services.AddSingleton<IMusicMetadataService>(sp =>
builder.Services.AddSingleton<IConcreteMetadataService, DeezerMetadataService>();
builder.Services.AddSingleton<IConcreteMetadataService, QobuzMetadataService>();
builder.Services.AddSingleton<IConcreteMetadataService, AppleMusicMetadataService>();
builder.Services.AddSingleton<IConcreteMetadataService>(sp =>
new SquidWTFMetadataService(
sp.GetRequiredService<IHttpClientFactory>(),
sp.GetRequiredService<Microsoft.Extensions.Options.IOptions<SubsonicSettings>>(),
@@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging;
namespace allstarr.Services.AppleMusic;
public class AppleMusicMetadataService : IMusicMetadataService
public class AppleMusicMetadataService : IConcreteMetadataService
{
private readonly HttpClient _httpClient;
private readonly AppleMusicSettings _settings;
@@ -11,7 +11,7 @@ public class MultiProviderDownloadService : IDownloadService
private readonly ProviderStatusManager _statusManager;
private readonly OdesliService _odesliService;
private readonly ILogger<MultiProviderDownloadService> _logger;
private readonly IEnumerable<IMusicMetadataService> _allMetadataServices;
private readonly IEnumerable<IConcreteMetadataService> _allMetadataServices;
public async Task<string> DownloadSongAsync(string externalProvider, string externalId, CancellationToken cancellationToken = default)
{
@@ -196,14 +196,14 @@ public class MultiProviderDownloadService : IDownloadService
public MultiProviderDownloadService(
IEnumerable<IDownloadService> services,
IEnumerable<IMusicMetadataService> metadataServices,
IEnumerable<IConcreteMetadataService> metadataServices,
IMusicMetadataService metadataService,
ProviderStatusManager statusManager,
OdesliService odesliService,
ILogger<MultiProviderDownloadService> logger)
{
_allServices = services.Where(s => s.GetType() != typeof(MultiProviderDownloadService)).ToList();
_allMetadataServices = metadataServices.Where(s => s.GetType() != typeof(MultiProviderMetadataService)).ToList();
_allMetadataServices = metadataServices.ToList();
_metadataService = metadataService;
_statusManager = statusManager;
_odesliService = odesliService;
@@ -7,18 +7,18 @@ namespace allstarr.Services.Common;
public class MultiProviderMetadataService : IMusicMetadataService
{
private readonly IEnumerable<IMusicMetadataService> _allServices;
private readonly IEnumerable<IConcreteMetadataService> _allServices;
private readonly ProviderStatusManager _statusManager;
private readonly ExtensionManager _extensionManager;
private readonly ILogger<MultiProviderMetadataService> _logger;
public MultiProviderMetadataService(
IEnumerable<IMusicMetadataService> services,
IEnumerable<IConcreteMetadataService> services,
ProviderStatusManager statusManager,
ExtensionManager extensionManager,
ILogger<MultiProviderMetadataService> logger)
{
_allServices = services.Where(s => s.GetType() != typeof(MultiProviderMetadataService)).ToList();
_allServices = services.ToList();
_statusManager = statusManager;
_extensionManager = extensionManager;
_logger = logger;
@@ -12,7 +12,7 @@ namespace allstarr.Services.Deezer;
/// <summary>
/// Metadata service implementation using the Deezer API (free, no key required)
/// </summary>
public class DeezerMetadataService : TrackParserBase, IMusicMetadataService
public class DeezerMetadataService : TrackParserBase, IConcreteMetadataService
{
private readonly HttpClient _httpClient;
private readonly SubsonicSettings _settings;
@@ -93,3 +93,10 @@ public interface IMusicMetadataService
/// <returns>List of songs in the playlist</returns>
Task<List<Song>> GetPlaylistTracksAsync(string externalProvider, string externalId, CancellationToken cancellationToken = default);
}
/// <summary>
/// Marker interface to distinguish concrete metadata services from orchestrator services.
/// </summary>
public interface IConcreteMetadataService : IMusicMetadataService
{
}
@@ -13,7 +13,7 @@ namespace allstarr.Services.Qobuz;
/// Metadata service implementation using the Qobuz API
/// Uses user authentication token instead of email/password
/// </summary>
public class QobuzMetadataService : TrackParserBase, IMusicMetadataService
public class QobuzMetadataService : TrackParserBase, IConcreteMetadataService
{
private readonly HttpClient _httpClient;
private readonly SubsonicSettings _settings;
@@ -52,7 +52,7 @@ namespace allstarr.Services.SquidWTF;
/// - Parallel Spotify ID conversion via Odesli for lyrics matching
/// </summary>
public class SquidWTFMetadataService : TrackParserBase, IMusicMetadataService
public class SquidWTFMetadataService : TrackParserBase, IConcreteMetadataService
{
private const int RemoteSearchMinLimit = 1;
private const int RemoteSearchMaxLimit = 500;
@@ -14,8 +14,8 @@ namespace allstarr.Services.Subsonic;
/// </summary>
public class PlaylistSyncService
{
private readonly IMusicMetadataService _deezerMetadataService;
private readonly IMusicMetadataService _qobuzMetadataService;
private readonly IConcreteMetadataService _deezerMetadataService;
private readonly IConcreteMetadataService _qobuzMetadataService;
private readonly IEnumerable<IDownloadService> _downloadServices;
private readonly IConfiguration _configuration;
private readonly SubsonicSettings _subsonicSettings;
@@ -35,7 +35,7 @@ public class PlaylistSyncService
private readonly Task _cleanupTask;
public PlaylistSyncService(
IEnumerable<IMusicMetadataService> metadataServices,
IEnumerable<IConcreteMetadataService> metadataServices,
IEnumerable<IDownloadService> downloadServices,
IConfiguration configuration,
IOptions<SubsonicSettings> subsonicSettings,