소스 검색

Register and construct LibraryManager correctly

Mark Monteiro 5 년 전
부모
커밋
fe9f4e06d1
2개의 변경된 파일107개의 추가작업 그리고 141개의 파일을 삭제
  1. 8 13
      Emby.Server.Implementations/ApplicationHost.cs
  2. 99 128
      Emby.Server.Implementations/Library/LibraryManager.cs

+ 8 - 13
Emby.Server.Implementations/ApplicationHost.cs

@@ -251,12 +251,6 @@ namespace Emby.Server.Implementations
         /// <value>The user manager.</value>
         public IUserManager UserManager { get; set; }
 
-        /// <summary>
-        /// Gets or sets the library manager.
-        /// </summary>
-        /// <value>The library manager.</value>
-        internal ILibraryManager LibraryManager { get; set; }
-
         /// <summary>
         /// Gets or sets the media encoder.
         /// </summary>
@@ -702,8 +696,11 @@ namespace Emby.Server.Implementations
                 StartupOptions.FFmpegPath);
             serviceCollection.AddSingleton(MediaEncoder);
 
-            LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, Resolve<ILibraryMonitor>, FileSystemManager, Resolve<IProviderManager>, Resolve<IUserViewManager>, MediaEncoder);
-            serviceCollection.AddSingleton(LibraryManager);
+            // TODO: Refactor to eliminate the circular dependencies here so that Lazy<T> isn't required
+            serviceCollection.AddTransient(provider => new Lazy<ILibraryMonitor>(provider.GetRequiredService<ILibraryMonitor>));
+            serviceCollection.AddTransient(provider => new Lazy<IProviderManager>(provider.GetRequiredService<IProviderManager>));
+            serviceCollection.AddTransient(provider => new Lazy<IUserViewManager>(provider.GetRequiredService<IUserViewManager>));
+            serviceCollection.AddSingleton<ILibraryManager, LibraryManager>();
 
             serviceCollection.AddSingleton<IMusicManager, MusicManager>();
 
@@ -789,9 +786,7 @@ namespace Emby.Server.Implementations
 
             ((UserDataManager)UserDataManager).Repository = userDataRepo;
 
-            var itemRepo = (SqliteItemRepository)Resolve<IItemRepository>();
-            itemRepo.Initialize(userDataRepo, UserManager);
-            ((LibraryManager)LibraryManager).ItemRepository = itemRepo;
+            ((SqliteItemRepository)Resolve<IItemRepository>()).Initialize(userDataRepo, UserManager);
 
             FindParts();
         }
@@ -894,7 +889,7 @@ namespace Emby.Server.Implementations
             // For now there's no real way to inject these properly
             BaseItem.Logger = LoggerFactory.CreateLogger("BaseItem");
             BaseItem.ConfigurationManager = ServerConfigurationManager;
-            BaseItem.LibraryManager = LibraryManager;
+            BaseItem.LibraryManager = Resolve<ILibraryManager>();
             BaseItem.ProviderManager = Resolve<IProviderManager>();
             BaseItem.LocalizationManager = LocalizationManager;
             BaseItem.ItemRepository = Resolve<IItemRepository>();
@@ -970,7 +965,7 @@ namespace Emby.Server.Implementations
 
             _httpServer.Init(GetExportTypes<IService>(), GetExports<IWebSocketListener>(), GetUrlPrefixes());
 
-            LibraryManager.AddParts(
+            Resolve<ILibraryManager>().AddParts(
                 GetExports<IResolverIgnoreRule>(),
                 GetExports<IItemResolver>(),
                 GetExports<IIntroProvider>(),

+ 99 - 128
Emby.Server.Implementations/Library/LibraryManager.cs

@@ -54,9 +54,29 @@ namespace Emby.Server.Implementations.Library
     /// </summary>
     public class LibraryManager : ILibraryManager
     {
+        private readonly ILogger _logger;
+        private readonly ITaskManager _taskManager;
+        private readonly IUserManager _userManager;
+        private readonly IUserDataManager _userDataRepository;
+        private readonly IServerConfigurationManager _configurationManager;
+        private readonly Lazy<ILibraryMonitor> _libraryMonitorFactory;
+        private readonly Lazy<IProviderManager> _providerManagerFactory;
+        private readonly Lazy<IUserViewManager> _userviewManagerFactory;
+        private readonly IServerApplicationHost _appHost;
+        private readonly IMediaEncoder _mediaEncoder;
+        private readonly IFileSystem _fileSystem;
+        private readonly IItemRepository _itemRepository;
+        private readonly ConcurrentDictionary<Guid, BaseItem> _libraryItemsCache;
+
         private NamingOptions _namingOptions;
         private string[] _videoFileExtensions;
 
+        private ILibraryMonitor LibraryMonitor => _libraryMonitorFactory.Value;
+
+        private IProviderManager ProviderManager => _providerManagerFactory.Value;
+
+        private IUserViewManager UserViewManager => _userviewManagerFactory.Value;
+
         /// <summary>
         /// Gets or sets the postscan tasks.
         /// </summary>
@@ -89,12 +109,6 @@ namespace Emby.Server.Implementations.Library
         /// <value>The comparers.</value>
         private IBaseItemComparer[] Comparers { get; set; }
 
-        /// <summary>
-        /// Gets or sets the active item repository
-        /// </summary>
-        /// <value>The item repository.</value>
-        public IItemRepository ItemRepository { get; set; }
-
         /// <summary>
         /// Occurs when [item added].
         /// </summary>
@@ -110,90 +124,47 @@ namespace Emby.Server.Implementations.Library
         /// </summary>
         public event EventHandler<ItemChangeEventArgs> ItemRemoved;
 
-        /// <summary>
-        /// The _logger
-        /// </summary>
-        private readonly ILogger _logger;
-
-        /// <summary>
-        /// The _task manager
-        /// </summary>
-        private readonly ITaskManager _taskManager;
-
-        /// <summary>
-        /// The _user manager
-        /// </summary>
-        private readonly IUserManager _userManager;
-
-        /// <summary>
-        /// The _user data repository
-        /// </summary>
-        private readonly IUserDataManager _userDataRepository;
-
-        /// <summary>
-        /// Gets or sets the configuration manager.
-        /// </summary>
-        /// <value>The configuration manager.</value>
-        private IServerConfigurationManager ConfigurationManager { get; set; }
-
-        private readonly Func<ILibraryMonitor> _libraryMonitorFactory;
-        private readonly Func<IProviderManager> _providerManagerFactory;
-        private readonly Func<IUserViewManager> _userviewManager;
         public bool IsScanRunning { get; private set; }
 
-        private IServerApplicationHost _appHost;
-        private readonly IMediaEncoder _mediaEncoder;
-
-        /// <summary>
-        /// The _library items cache
-        /// </summary>
-        private readonly ConcurrentDictionary<Guid, BaseItem> _libraryItemsCache;
-
-        /// <summary>
-        /// Gets the library items cache.
-        /// </summary>
-        /// <value>The library items cache.</value>
-        private ConcurrentDictionary<Guid, BaseItem> LibraryItemsCache => _libraryItemsCache;
-
-        private readonly IFileSystem _fileSystem;
-
         /// <summary>
         /// Initializes a new instance of the <see cref="LibraryManager" /> class.
         /// </summary>
         /// <param name="appHost">The application host</param>
-        /// <param name="loggerFactory">The logger factory.</param>
+        /// <param name="logger">The logger.</param>
         /// <param name="taskManager">The task manager.</param>
         /// <param name="userManager">The user manager.</param>
         /// <param name="configurationManager">The configuration manager.</param>
         /// <param name="userDataRepository">The user data repository.</param>
         public LibraryManager(
             IServerApplicationHost appHost,
-            ILoggerFactory loggerFactory,
+            ILogger<LibraryManager> logger,
             ITaskManager taskManager,
             IUserManager userManager,
             IServerConfigurationManager configurationManager,
             IUserDataManager userDataRepository,
-            Func<ILibraryMonitor> libraryMonitorFactory,
+            Lazy<ILibraryMonitor> libraryMonitorFactory,
             IFileSystem fileSystem,
-            Func<IProviderManager> providerManagerFactory,
-            Func<IUserViewManager> userviewManager,
-            IMediaEncoder mediaEncoder)
+            Lazy<IProviderManager> providerManagerFactory,
+            Lazy<IUserViewManager> userviewManagerFactory,
+            IMediaEncoder mediaEncoder,
+            IItemRepository itemRepository)
         {
             _appHost = appHost;
-            _logger = loggerFactory.CreateLogger(nameof(LibraryManager));
+            _logger = logger;
             _taskManager = taskManager;
             _userManager = userManager;
-            ConfigurationManager = configurationManager;
+            _configurationManager = configurationManager;
             _userDataRepository = userDataRepository;
             _libraryMonitorFactory = libraryMonitorFactory;
             _fileSystem = fileSystem;
             _providerManagerFactory = providerManagerFactory;
-            _userviewManager = userviewManager;
+            _userviewManagerFactory = userviewManagerFactory;
             _mediaEncoder = mediaEncoder;
+            _itemRepository = itemRepository;
 
             _libraryItemsCache = new ConcurrentDictionary<Guid, BaseItem>();
 
-            ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated;
+            _configurationManager.ConfigurationUpdated += ConfigurationUpdated;
 
             RecordConfigurationValues(configurationManager.Configuration);
         }
@@ -272,7 +243,7 @@ namespace Emby.Server.Implementations.Library
         /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
         private void ConfigurationUpdated(object sender, EventArgs e)
         {
-            var config = ConfigurationManager.Configuration;
+            var config = _configurationManager.Configuration;
 
             var wizardChanged = config.IsStartupWizardCompleted != _wizardCompleted;
 
@@ -306,7 +277,7 @@ namespace Emby.Server.Implementations.Library
                 }
             }
 
-            LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
+            _libraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; });
         }
 
         public void DeleteItem(BaseItem item, DeleteOptions options)
@@ -437,10 +408,10 @@ namespace Emby.Server.Implementations.Library
 
             item.SetParent(null);
 
-            ItemRepository.DeleteItem(item.Id, CancellationToken.None);
+            _itemRepository.DeleteItem(item.Id, CancellationToken.None);
             foreach (var child in children)
             {
-                ItemRepository.DeleteItem(child.Id, CancellationToken.None);
+                _itemRepository.DeleteItem(child.Id, CancellationToken.None);
             }
 
             _libraryItemsCache.TryRemove(item.Id, out BaseItem removed);
@@ -509,15 +480,15 @@ namespace Emby.Server.Implementations.Library
                 throw new ArgumentNullException(nameof(type));
             }
 
-            if (key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath, StringComparison.Ordinal))
+            if (key.StartsWith(_configurationManager.ApplicationPaths.ProgramDataPath, StringComparison.Ordinal))
             {
                 // Try to normalize paths located underneath program-data in an attempt to make them more portable
-                key = key.Substring(ConfigurationManager.ApplicationPaths.ProgramDataPath.Length)
+                key = key.Substring(_configurationManager.ApplicationPaths.ProgramDataPath.Length)
                     .TrimStart(new[] { '/', '\\' })
                     .Replace("/", "\\");
             }
 
-            if (forceCaseInsensitive || !ConfigurationManager.Configuration.EnableCaseSensitiveItemIds)
+            if (forceCaseInsensitive || !_configurationManager.Configuration.EnableCaseSensitiveItemIds)
             {
                 key = key.ToLowerInvariant();
             }
@@ -550,7 +521,7 @@ namespace Emby.Server.Implementations.Library
                 collectionType = GetContentTypeOverride(fullPath, true);
             }
 
-            var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService)
+            var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService)
             {
                 Parent = parent,
                 Path = fullPath,
@@ -720,7 +691,7 @@ namespace Emby.Server.Implementations.Library
         /// <exception cref="InvalidOperationException">Cannot create the root folder until plugins have loaded.</exception>
         public AggregateFolder CreateRootFolder()
         {
-            var rootFolderPath = ConfigurationManager.ApplicationPaths.RootFolderPath;
+            var rootFolderPath = _configurationManager.ApplicationPaths.RootFolderPath;
 
             Directory.CreateDirectory(rootFolderPath);
 
@@ -734,7 +705,7 @@ namespace Emby.Server.Implementations.Library
             }
 
             // Add in the plug-in folders
-            var path = Path.Combine(ConfigurationManager.ApplicationPaths.DataPath, "playlists");
+            var path = Path.Combine(_configurationManager.ApplicationPaths.DataPath, "playlists");
 
             Directory.CreateDirectory(path);
 
@@ -786,7 +757,7 @@ namespace Emby.Server.Implementations.Library
                 {
                     if (_userRootFolder == null)
                     {
-                        var userRootPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+                        var userRootPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
 
                         _logger.LogDebug("Creating userRootPath at {path}", userRootPath);
                         Directory.CreateDirectory(userRootPath);
@@ -980,7 +951,7 @@ namespace Emby.Server.Implementations.Library
               where T : BaseItem, new()
         {
             var path = getPathFn(name);
-            var forceCaseInsensitiveId = ConfigurationManager.Configuration.EnableNormalizedItemByNameIds;
+            var forceCaseInsensitiveId = _configurationManager.Configuration.EnableNormalizedItemByNameIds;
             return GetNewItemIdInternal(path, typeof(T), forceCaseInsensitiveId);
         }
 
@@ -994,7 +965,7 @@ namespace Emby.Server.Implementations.Library
         public Task ValidatePeople(CancellationToken cancellationToken, IProgress<double> progress)
         {
             // Ensure the location is available.
-            Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.PeoplePath);
+            Directory.CreateDirectory(_configurationManager.ApplicationPaths.PeoplePath);
 
             return new PeopleValidator(this, _logger, _fileSystem).ValidatePeople(cancellationToken, progress);
         }
@@ -1031,7 +1002,7 @@ namespace Emby.Server.Implementations.Library
         public async Task ValidateMediaLibraryInternal(IProgress<double> progress, CancellationToken cancellationToken)
         {
             IsScanRunning = true;
-            _libraryMonitorFactory().Stop();
+            LibraryMonitor.Stop();
 
             try
             {
@@ -1039,7 +1010,7 @@ namespace Emby.Server.Implementations.Library
             }
             finally
             {
-                _libraryMonitorFactory().Start();
+                LibraryMonitor.Start();
                 IsScanRunning = false;
             }
         }
@@ -1148,7 +1119,7 @@ namespace Emby.Server.Implementations.Library
                 progress.Report(percent * 100);
             }
 
-            ItemRepository.UpdateInheritedValues(cancellationToken);
+            _itemRepository.UpdateInheritedValues(cancellationToken);
 
             progress.Report(100);
         }
@@ -1168,9 +1139,9 @@ namespace Emby.Server.Implementations.Library
             var topLibraryFolders = GetUserRootFolder().Children.ToList();
 
             _logger.LogDebug("Getting refreshQueue");
-            var refreshQueue = includeRefreshState ? _providerManagerFactory().GetRefreshQueue() : null;
+            var refreshQueue = includeRefreshState ? ProviderManager.GetRefreshQueue() : null;
 
-            return _fileSystem.GetDirectoryPaths(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath)
+            return _fileSystem.GetDirectoryPaths(_configurationManager.ApplicationPaths.DefaultUserViewsPath)
                 .Select(dir => GetVirtualFolderInfo(dir, topLibraryFolders, refreshQueue))
                 .ToList();
         }
@@ -1245,7 +1216,7 @@ namespace Emby.Server.Implementations.Library
                 throw new ArgumentException("Guid can't be empty", nameof(id));
             }
 
-            if (LibraryItemsCache.TryGetValue(id, out BaseItem item))
+            if (_libraryItemsCache.TryGetValue(id, out BaseItem item))
             {
                 return item;
             }
@@ -1276,7 +1247,7 @@ namespace Emby.Server.Implementations.Library
                 AddUserToQuery(query, query.User, allowExternalContent);
             }
 
-            return ItemRepository.GetItemList(query);
+            return _itemRepository.GetItemList(query);
         }
 
         public List<BaseItem> GetItemList(InternalItemsQuery query)
@@ -1300,7 +1271,7 @@ namespace Emby.Server.Implementations.Library
                 AddUserToQuery(query, query.User);
             }
 
-            return ItemRepository.GetCount(query);
+            return _itemRepository.GetCount(query);
         }
 
         public List<BaseItem> GetItemList(InternalItemsQuery query, List<BaseItem> parents)
@@ -1315,7 +1286,7 @@ namespace Emby.Server.Implementations.Library
                 }
             }
 
-            return ItemRepository.GetItemList(query);
+            return _itemRepository.GetItemList(query);
         }
 
         public QueryResult<BaseItem> QueryItems(InternalItemsQuery query)
@@ -1327,12 +1298,12 @@ namespace Emby.Server.Implementations.Library
 
             if (query.EnableTotalRecordCount)
             {
-                return ItemRepository.GetItems(query);
+                return _itemRepository.GetItems(query);
             }
 
             return new QueryResult<BaseItem>
             {
-                Items = ItemRepository.GetItemList(query).ToArray()
+                Items = _itemRepository.GetItemList(query).ToArray()
             };
         }
 
@@ -1343,7 +1314,7 @@ namespace Emby.Server.Implementations.Library
                 AddUserToQuery(query, query.User);
             }
 
-            return ItemRepository.GetItemIdsList(query);
+            return _itemRepository.GetItemIdsList(query);
         }
 
         public QueryResult<(BaseItem, ItemCounts)> GetStudios(InternalItemsQuery query)
@@ -1354,7 +1325,7 @@ namespace Emby.Server.Implementations.Library
             }
 
             SetTopParentOrAncestorIds(query);
-            return ItemRepository.GetStudios(query);
+            return _itemRepository.GetStudios(query);
         }
 
         public QueryResult<(BaseItem, ItemCounts)> GetGenres(InternalItemsQuery query)
@@ -1365,7 +1336,7 @@ namespace Emby.Server.Implementations.Library
             }
 
             SetTopParentOrAncestorIds(query);
-            return ItemRepository.GetGenres(query);
+            return _itemRepository.GetGenres(query);
         }
 
         public QueryResult<(BaseItem, ItemCounts)> GetMusicGenres(InternalItemsQuery query)
@@ -1376,7 +1347,7 @@ namespace Emby.Server.Implementations.Library
             }
 
             SetTopParentOrAncestorIds(query);
-            return ItemRepository.GetMusicGenres(query);
+            return _itemRepository.GetMusicGenres(query);
         }
 
         public QueryResult<(BaseItem, ItemCounts)> GetAllArtists(InternalItemsQuery query)
@@ -1387,7 +1358,7 @@ namespace Emby.Server.Implementations.Library
             }
 
             SetTopParentOrAncestorIds(query);
-            return ItemRepository.GetAllArtists(query);
+            return _itemRepository.GetAllArtists(query);
         }
 
         public QueryResult<(BaseItem, ItemCounts)> GetArtists(InternalItemsQuery query)
@@ -1398,7 +1369,7 @@ namespace Emby.Server.Implementations.Library
             }
 
             SetTopParentOrAncestorIds(query);
-            return ItemRepository.GetArtists(query);
+            return _itemRepository.GetArtists(query);
         }
 
         private void SetTopParentOrAncestorIds(InternalItemsQuery query)
@@ -1439,7 +1410,7 @@ namespace Emby.Server.Implementations.Library
             }
 
             SetTopParentOrAncestorIds(query);
-            return ItemRepository.GetAlbumArtists(query);
+            return _itemRepository.GetAlbumArtists(query);
         }
 
         public QueryResult<BaseItem> GetItemsResult(InternalItemsQuery query)
@@ -1460,10 +1431,10 @@ namespace Emby.Server.Implementations.Library
 
             if (query.EnableTotalRecordCount)
             {
-                return ItemRepository.GetItems(query);
+                return _itemRepository.GetItems(query);
             }
 
-            var list = ItemRepository.GetItemList(query);
+            var list = _itemRepository.GetItemList(query);
 
             return new QueryResult<BaseItem>
             {
@@ -1509,7 +1480,7 @@ namespace Emby.Server.Implementations.Library
                 string.IsNullOrEmpty(query.SeriesPresentationUniqueKey) &&
                 query.ItemIds.Length == 0)
             {
-                var userViews = _userviewManager().GetUserViews(new UserViewQuery
+                var userViews = UserViewManager.GetUserViews(new UserViewQuery
                 {
                     UserId = user.Id,
                     IncludeHidden = true,
@@ -1809,7 +1780,7 @@ namespace Emby.Server.Implementations.Library
             // Don't iterate multiple times
             var itemsList = items.ToList();
 
-            ItemRepository.SaveItems(itemsList, cancellationToken);
+            _itemRepository.SaveItems(itemsList, cancellationToken);
 
             foreach (var item in itemsList)
             {
@@ -1846,7 +1817,7 @@ namespace Emby.Server.Implementations.Library
 
         public void UpdateImages(BaseItem item)
         {
-            ItemRepository.SaveImages(item);
+            _itemRepository.SaveImages(item);
 
             RegisterItem(item);
         }
@@ -1863,7 +1834,7 @@ namespace Emby.Server.Implementations.Library
             {
                 if (item.IsFileProtocol)
                 {
-                    _providerManagerFactory().SaveMetadata(item, updateReason);
+                    ProviderManager.SaveMetadata(item, updateReason);
                 }
 
                 item.DateLastSaved = DateTime.UtcNow;
@@ -1871,7 +1842,7 @@ namespace Emby.Server.Implementations.Library
                 RegisterItem(item);
             }
 
-            ItemRepository.SaveItems(itemsList, cancellationToken);
+            _itemRepository.SaveItems(itemsList, cancellationToken);
 
             if (ItemUpdated != null)
             {
@@ -1947,7 +1918,7 @@ namespace Emby.Server.Implementations.Library
         /// <returns>BaseItem.</returns>
         public BaseItem RetrieveItem(Guid id)
         {
-            return ItemRepository.RetrieveItem(id);
+            return _itemRepository.RetrieveItem(id);
         }
 
         public List<Folder> GetCollectionFolders(BaseItem item)
@@ -2066,7 +2037,7 @@ namespace Emby.Server.Implementations.Library
 
         private string GetContentTypeOverride(string path, bool inherit)
         {
-            var nameValuePair = ConfigurationManager.Configuration.ContentTypes
+            var nameValuePair = _configurationManager.Configuration.ContentTypes
                                     .FirstOrDefault(i => _fileSystem.AreEqual(i.Name, path)
                                                          || (inherit && !string.IsNullOrEmpty(i.Name)
                                                                      && _fileSystem.ContainsSubPath(i.Name, path)));
@@ -2115,7 +2086,7 @@ namespace Emby.Server.Implementations.Library
             string sortName)
         {
             var path = Path.Combine(
-                ConfigurationManager.ApplicationPaths.InternalMetadataPath,
+                _configurationManager.ApplicationPaths.InternalMetadataPath,
                 "views",
                 _fileSystem.GetValidFilename(viewType));
 
@@ -2147,7 +2118,7 @@ namespace Emby.Server.Implementations.Library
             if (refresh)
             {
                 item.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None);
-                _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal);
+                ProviderManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal);
             }
 
             return item;
@@ -2165,7 +2136,7 @@ namespace Emby.Server.Implementations.Library
 
             var id = GetNewItemId(idValues, typeof(UserView));
 
-            var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
+            var path = Path.Combine(_configurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
 
             var item = GetItemById(id) as UserView;
 
@@ -2202,7 +2173,7 @@ namespace Emby.Server.Implementations.Library
 
             if (refresh)
             {
-                _providerManagerFactory().QueueRefresh(
+                ProviderManager.QueueRefresh(
                     item.Id,
                     new MetadataRefreshOptions(new DirectoryService(_fileSystem))
                     {
@@ -2269,7 +2240,7 @@ namespace Emby.Server.Implementations.Library
 
             if (refresh)
             {
-                _providerManagerFactory().QueueRefresh(
+                ProviderManager.QueueRefresh(
                     item.Id,
                     new MetadataRefreshOptions(new DirectoryService(_fileSystem))
                     {
@@ -2303,7 +2274,7 @@ namespace Emby.Server.Implementations.Library
 
             var id = GetNewItemId(idValues, typeof(UserView));
 
-            var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
+            var path = Path.Combine(_configurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
 
             var item = GetItemById(id) as UserView;
 
@@ -2346,7 +2317,7 @@ namespace Emby.Server.Implementations.Library
 
             if (refresh)
             {
-                _providerManagerFactory().QueueRefresh(
+                ProviderManager.QueueRefresh(
                     item.Id,
                     new MetadataRefreshOptions(new DirectoryService(_fileSystem))
                     {
@@ -2677,8 +2648,8 @@ namespace Emby.Server.Implementations.Library
                 }
             }
 
-            var metadataPath = ConfigurationManager.Configuration.MetadataPath;
-            var metadataNetworkPath = ConfigurationManager.Configuration.MetadataNetworkPath;
+            var metadataPath = _configurationManager.Configuration.MetadataPath;
+            var metadataNetworkPath = _configurationManager.Configuration.MetadataNetworkPath;
 
             if (!string.IsNullOrWhiteSpace(metadataPath) && !string.IsNullOrWhiteSpace(metadataNetworkPath))
             {
@@ -2689,7 +2660,7 @@ namespace Emby.Server.Implementations.Library
                 }
             }
 
-            foreach (var map in ConfigurationManager.Configuration.PathSubstitutions)
+            foreach (var map in _configurationManager.Configuration.PathSubstitutions)
             {
                 if (!string.IsNullOrWhiteSpace(map.From))
                 {
@@ -2758,7 +2729,7 @@ namespace Emby.Server.Implementations.Library
 
         public List<PersonInfo> GetPeople(InternalPeopleQuery query)
         {
-            return ItemRepository.GetPeople(query);
+            return _itemRepository.GetPeople(query);
         }
 
         public List<PersonInfo> GetPeople(BaseItem item)
@@ -2781,7 +2752,7 @@ namespace Emby.Server.Implementations.Library
 
         public List<Person> GetPeopleItems(InternalPeopleQuery query)
         {
-            return ItemRepository.GetPeopleNames(query).Select(i =>
+            return _itemRepository.GetPeopleNames(query).Select(i =>
             {
                 try
                 {
@@ -2798,7 +2769,7 @@ namespace Emby.Server.Implementations.Library
 
         public List<string> GetPeopleNames(InternalPeopleQuery query)
         {
-            return ItemRepository.GetPeopleNames(query);
+            return _itemRepository.GetPeopleNames(query);
         }
 
         public void UpdatePeople(BaseItem item, List<PersonInfo> people)
@@ -2808,7 +2779,7 @@ namespace Emby.Server.Implementations.Library
                 return;
             }
 
-            ItemRepository.UpdatePeople(item.Id, people);
+            _itemRepository.UpdatePeople(item.Id, people);
         }
 
         public async Task<ItemImageInfo> ConvertImageToLocal(BaseItem item, ItemImageInfo image, int imageIndex)
@@ -2819,7 +2790,7 @@ namespace Emby.Server.Implementations.Library
                 {
                     _logger.LogDebug("ConvertImageToLocal item {0} - image url: {1}", item.Id, url);
 
-                    await _providerManagerFactory().SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
+                    await ProviderManager.SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
 
                     item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
 
@@ -2852,7 +2823,7 @@ namespace Emby.Server.Implementations.Library
 
             name = _fileSystem.GetValidFilename(name);
 
-            var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+            var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
 
             var virtualFolderPath = Path.Combine(rootFolderPath, name);
             while (Directory.Exists(virtualFolderPath))
@@ -2871,7 +2842,7 @@ namespace Emby.Server.Implementations.Library
                 }
             }
 
-            _libraryMonitorFactory().Stop();
+            LibraryMonitor.Stop();
 
             try
             {
@@ -2906,7 +2877,7 @@ namespace Emby.Server.Implementations.Library
                 {
                     // Need to add a delay here or directory watchers may still pick up the changes
                     await Task.Delay(1000).ConfigureAwait(false);
-                    _libraryMonitorFactory().Start();
+                    LibraryMonitor.Start();
                 }
             }
         }
@@ -2966,7 +2937,7 @@ namespace Emby.Server.Implementations.Library
                 throw new FileNotFoundException("The network path does not exist.");
             }
 
-            var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+            var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
             var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
 
             var shortcutFilename = Path.GetFileNameWithoutExtension(path);
@@ -3009,7 +2980,7 @@ namespace Emby.Server.Implementations.Library
                 throw new FileNotFoundException("The network path does not exist.");
             }
 
-            var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+            var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
             var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
 
             var libraryOptions = CollectionFolder.GetLibraryOptions(virtualFolderPath);
@@ -3062,7 +3033,7 @@ namespace Emby.Server.Implementations.Library
                 throw new ArgumentNullException(nameof(name));
             }
 
-            var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+            var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
 
             var path = Path.Combine(rootFolderPath, name);
 
@@ -3071,7 +3042,7 @@ namespace Emby.Server.Implementations.Library
                 throw new FileNotFoundException("The media folder does not exist");
             }
 
-            _libraryMonitorFactory().Stop();
+            LibraryMonitor.Stop();
 
             try
             {
@@ -3091,7 +3062,7 @@ namespace Emby.Server.Implementations.Library
                 {
                     // Need to add a delay here or directory watchers may still pick up the changes
                     await Task.Delay(1000).ConfigureAwait(false);
-                    _libraryMonitorFactory().Start();
+                    LibraryMonitor.Start();
                 }
             }
         }
@@ -3105,7 +3076,7 @@ namespace Emby.Server.Implementations.Library
 
             var removeList = new List<NameValuePair>();
 
-            foreach (var contentType in ConfigurationManager.Configuration.ContentTypes)
+            foreach (var contentType in _configurationManager.Configuration.ContentTypes)
             {
                 if (string.IsNullOrWhiteSpace(contentType.Name))
                 {
@@ -3120,11 +3091,11 @@ namespace Emby.Server.Implementations.Library
 
             if (removeList.Count > 0)
             {
-                ConfigurationManager.Configuration.ContentTypes = ConfigurationManager.Configuration.ContentTypes
+                _configurationManager.Configuration.ContentTypes = _configurationManager.Configuration.ContentTypes
                     .Except(removeList)
                         .ToArray();
 
-                ConfigurationManager.SaveConfiguration();
+                _configurationManager.SaveConfiguration();
             }
         }
 
@@ -3135,7 +3106,7 @@ namespace Emby.Server.Implementations.Library
                 throw new ArgumentNullException(nameof(mediaPath));
             }
 
-            var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+            var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
             var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
 
             if (!Directory.Exists(virtualFolderPath))