Merge pull request #2765 from mark-monteiro/register-services-correctly

Register And Construct Services Correctly Using DI Framework
pull/2961/head
Bond-009 4 years ago committed by GitHub
commit 07c4dfd8fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,7 +8,6 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
@ -33,8 +32,7 @@ namespace Emby.Drawing
private readonly IFileSystem _fileSystem;
private readonly IServerApplicationPaths _appPaths;
private readonly IImageEncoder _imageEncoder;
private readonly Func<ILibraryManager> _libraryManager;
private readonly Func<IMediaEncoder> _mediaEncoder;
private readonly IMediaEncoder _mediaEncoder;
private bool _disposed = false;
@ -45,20 +43,17 @@ namespace Emby.Drawing
/// <param name="appPaths">The server application paths.</param>
/// <param name="fileSystem">The filesystem.</param>
/// <param name="imageEncoder">The image encoder.</param>
/// <param name="libraryManager">The library manager.</param>
/// <param name="mediaEncoder">The media encoder.</param>
public ImageProcessor(
ILogger<ImageProcessor> logger,
IServerApplicationPaths appPaths,
IFileSystem fileSystem,
IImageEncoder imageEncoder,
Func<ILibraryManager> libraryManager,
Func<IMediaEncoder> mediaEncoder)
IMediaEncoder mediaEncoder)
{
_logger = logger;
_fileSystem = fileSystem;
_imageEncoder = imageEncoder;
_libraryManager = libraryManager;
_mediaEncoder = mediaEncoder;
_appPaths = appPaths;
}
@ -126,21 +121,9 @@ namespace Emby.Drawing
throw new ArgumentNullException(nameof(options));
}
var libraryManager = _libraryManager();
ItemImageInfo originalImage = options.Image;
BaseItem item = options.Item;
if (!originalImage.IsLocalFile)
{
if (item == null)
{
item = libraryManager.GetItemById(options.ItemId);
}
originalImage = await libraryManager.ConvertImageToLocal(item, originalImage, options.ImageIndex).ConfigureAwait(false);
}
string originalImagePath = originalImage.Path;
DateTime dateModified = originalImage.DateModified;
ImageDimensions? originalImageSize = null;
@ -312,10 +295,6 @@ namespace Emby.Drawing
/// <inheritdoc />
public ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info)
=> GetImageDimensions(item, info, true);
/// <inheritdoc />
public ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info, bool updateItem)
{
int width = info.Width;
int height = info.Height;
@ -332,11 +311,6 @@ namespace Emby.Drawing
info.Width = size.Width;
info.Height = size.Height;
if (updateItem)
{
_libraryManager().UpdateImages(item);
}
return size;
}
@ -384,13 +358,13 @@ namespace Emby.Drawing
{
string filename = (originalImagePath + dateModified.Ticks.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("N", CultureInfo.InvariantCulture);
string cacheExtension = _mediaEncoder().SupportsEncoder("libwebp") ? ".webp" : ".png";
string cacheExtension = _mediaEncoder.SupportsEncoder("libwebp") ? ".webp" : ".png";
var outputPath = Path.Combine(_appPaths.ImageCachePath, "converted-images", filename + cacheExtension);
var file = _fileSystem.GetFileInfo(outputPath);
if (!file.Exists)
{
await _mediaEncoder().ConvertImage(originalImagePath, outputPath).ConfigureAwait(false);
await _mediaEncoder.ConvertImage(originalImagePath, outputPath).ConfigureAwait(false);
dateModified = _fileSystem.GetLastWriteTimeUtc(outputPath);
}
else

@ -160,7 +160,7 @@ namespace Emby.Photos
try
{
var size = _imageProcessor.GetImageDimensions(item, img, false);
var size = _imageProcessor.GetImageDimensions(item, img);
if (size.Width > 0 && size.Height > 0)
{

@ -86,7 +86,6 @@ using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
@ -104,7 +103,6 @@ using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
@ -121,14 +119,20 @@ namespace Emby.Server.Implementations
/// </summary>
private static readonly string[] _relevantEnvVarPrefixes = { "JELLYFIN_", "DOTNET_", "ASPNETCORE_" };
private SqliteUserRepository _userRepository;
private SqliteDisplayPreferencesRepository _displayPreferencesRepository;
private readonly IFileSystem _fileSystemManager;
private readonly INetworkManager _networkManager;
private readonly IXmlSerializer _xmlSerializer;
private readonly IStartupOptions _startupOptions;
private IMediaEncoder _mediaEncoder;
private ISessionManager _sessionManager;
private IHttpServer _httpServer;
private IHttpClient _httpClient;
/// <summary>
/// Gets a value indicating whether this instance can self restart.
/// </summary>
/// <value><c>true</c> if this instance can self restart; otherwise, <c>false</c>.</value>
public abstract bool CanSelfRestart { get; }
public bool CanSelfRestart => _startupOptions.RestartPath != null;
public virtual bool CanLaunchWebBrowser
{
@ -139,7 +143,7 @@ namespace Emby.Server.Implementations
return false;
}
if (StartupOptions.IsService)
if (_startupOptions.IsService)
{
return false;
}
@ -209,8 +213,6 @@ namespace Emby.Server.Implementations
/// <value>The configuration manager.</value>
protected IConfigurationManager ConfigurationManager { get; set; }
public IFileSystem FileSystemManager { get; set; }
/// <summary>
/// Gets or sets the service provider.
/// </summary>
@ -232,110 +234,6 @@ namespace Emby.Server.Implementations
/// <value>The server configuration manager.</value>
public IServerConfigurationManager ServerConfigurationManager => (IServerConfigurationManager)ConfigurationManager;
/// <summary>
/// Gets or sets the user manager.
/// </summary>
/// <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 directory watchers.
/// </summary>
/// <value>The directory watchers.</value>
private ILibraryMonitor LibraryMonitor { get; set; }
/// <summary>
/// Gets or sets the provider manager.
/// </summary>
/// <value>The provider manager.</value>
private IProviderManager ProviderManager { get; set; }
/// <summary>
/// Gets or sets the HTTP server.
/// </summary>
/// <value>The HTTP server.</value>
private IHttpServer HttpServer { get; set; }
private IDtoService DtoService { get; set; }
public IImageProcessor ImageProcessor { get; set; }
/// <summary>
/// Gets or sets the media encoder.
/// </summary>
/// <value>The media encoder.</value>
private IMediaEncoder MediaEncoder { get; set; }
private ISubtitleEncoder SubtitleEncoder { get; set; }
private ISessionManager SessionManager { get; set; }
private ILiveTvManager LiveTvManager { get; set; }
public LocalizationManager LocalizationManager { get; set; }
private IEncodingManager EncodingManager { get; set; }
private IChannelManager ChannelManager { get; set; }
/// <summary>
/// Gets or sets the user data repository.
/// </summary>
/// <value>The user data repository.</value>
private IUserDataManager UserDataManager { get; set; }
internal SqliteItemRepository ItemRepository { get; set; }
private INotificationManager NotificationManager { get; set; }
private ISubtitleManager SubtitleManager { get; set; }
private IChapterManager ChapterManager { get; set; }
private IDeviceManager DeviceManager { get; set; }
internal IUserViewManager UserViewManager { get; set; }
private IAuthenticationRepository AuthenticationRepository { get; set; }
private ITVSeriesManager TVSeriesManager { get; set; }
private ICollectionManager CollectionManager { get; set; }
private IMediaSourceManager MediaSourceManager { get; set; }
/// <summary>
/// Gets the installation manager.
/// </summary>
/// <value>The installation manager.</value>
protected IInstallationManager InstallationManager { get; private set; }
protected IAuthService AuthService { get; private set; }
public IStartupOptions StartupOptions { get; }
internal IImageEncoder ImageEncoder { get; private set; }
protected readonly IXmlSerializer XmlSerializer;
protected ISocketFactory SocketFactory { get; private set; }
protected ITaskManager TaskManager { get; private set; }
public IHttpClient HttpClient { get; private set; }
protected INetworkManager NetworkManager { get; set; }
public IJsonSerializer JsonSerializer { get; private set; }
protected IIsoManager IsoManager { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="ApplicationHost" /> class.
/// </summary>
@ -344,29 +242,33 @@ namespace Emby.Server.Implementations
ILoggerFactory loggerFactory,
IStartupOptions options,
IFileSystem fileSystem,
IImageEncoder imageEncoder,
INetworkManager networkManager)
{
XmlSerializer = new MyXmlSerializer();
_xmlSerializer = new MyXmlSerializer();
NetworkManager = networkManager;
_networkManager = networkManager;
networkManager.LocalSubnetsFn = GetConfiguredLocalSubnets;
ApplicationPaths = applicationPaths;
LoggerFactory = loggerFactory;
FileSystemManager = fileSystem;
_fileSystemManager = fileSystem;
ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, XmlSerializer, FileSystemManager);
ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, _xmlSerializer, _fileSystemManager);
Logger = LoggerFactory.CreateLogger("App");
Logger = LoggerFactory.CreateLogger<ApplicationHost>();
StartupOptions = options;
ImageEncoder = imageEncoder;
_startupOptions = options;
fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem));
NetworkManager.NetworkChanged += OnNetworkChanged;
_networkManager.NetworkChanged += OnNetworkChanged;
CertificateInfo = new CertificateInfo
{
Path = ServerConfigurationManager.Configuration.CertificatePath,
Password = ServerConfigurationManager.Configuration.CertificatePassword
};
Certificate = GetCertificate(CertificateInfo);
}
public string ExpandVirtualPath(string path)
@ -434,10 +336,7 @@ namespace Emby.Server.Implementations
}
}
/// <summary>
/// Gets the name.
/// </summary>
/// <value>The name.</value>
/// <inheritdoc/>
public string Name => ApplicationProductName;
/// <summary>
@ -527,7 +426,7 @@ namespace Emby.Server.Implementations
ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated;
MediaEncoder.SetFFmpegPath();
_mediaEncoder.SetFFmpegPath();
Logger.LogInformation("ServerId: {0}", SystemId);
@ -539,7 +438,7 @@ namespace Emby.Server.Implementations
Logger.LogInformation("Executed all pre-startup entry points in {Elapsed:g}", stopWatch.Elapsed);
Logger.LogInformation("Core startup complete");
HttpServer.GlobalResponse = null;
_httpServer.GlobalResponse = null;
stopWatch.Restart();
await Task.WhenAll(StartEntryPoints(entryPoints, false)).ConfigureAwait(false);
@ -563,7 +462,7 @@ namespace Emby.Server.Implementations
}
/// <inheritdoc/>
public async Task InitAsync(IServiceCollection serviceCollection, IConfiguration startupConfig)
public void Init(IServiceCollection serviceCollection)
{
HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber;
HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber;
@ -575,8 +474,6 @@ namespace Emby.Server.Implementations
HttpsPort = ServerConfiguration.DefaultHttpsPort;
}
JsonSerializer = new JsonSerializer();
if (Plugins != null)
{
var pluginBuilder = new StringBuilder();
@ -596,7 +493,7 @@ namespace Emby.Server.Implementations
DiscoverTypes();
await RegisterServices(serviceCollection, startupConfig).ConfigureAwait(false);
RegisterServices(serviceCollection);
}
public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next)
@ -607,7 +504,7 @@ namespace Emby.Server.Implementations
return;
}
await HttpServer.ProcessWebSocketRequest(context).ConfigureAwait(false);
await _httpServer.ProcessWebSocketRequest(context).ConfigureAwait(false);
}
public async Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next)
@ -623,14 +520,16 @@ namespace Emby.Server.Implementations
var localPath = context.Request.Path.ToString();
var req = new WebSocketSharpRequest(request, response, request.Path, LoggerFactory.CreateLogger<WebSocketSharpRequest>());
await HttpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false);
await _httpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false);
}
/// <summary>
/// Registers services/resources with the service collection that will be available via DI.
/// </summary>
protected async Task RegisterServices(IServiceCollection serviceCollection, IConfiguration startupConfig)
protected virtual void RegisterServices(IServiceCollection serviceCollection)
{
serviceCollection.AddSingleton(_startupOptions);
serviceCollection.AddMemoryCache();
serviceCollection.AddSingleton(ConfigurationManager);
@ -638,240 +537,169 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IApplicationPaths>(ApplicationPaths);
serviceCollection.AddSingleton(JsonSerializer);
serviceCollection.AddSingleton<IJsonSerializer, JsonSerializer>();
// TODO: Support for injecting ILogger should be deprecated in favour of ILogger<T> and this removed
serviceCollection.AddSingleton<ILogger>(Logger);
// TODO: Remove support for injecting ILogger completely
serviceCollection.AddSingleton((provider) =>
{
Logger.LogWarning("Injecting ILogger directly is deprecated and should be replaced with ILogger<T>");
return Logger;
});
serviceCollection.AddSingleton(FileSystemManager);
serviceCollection.AddSingleton(_fileSystemManager);
serviceCollection.AddSingleton<TvdbClientManager>();
HttpClient = new HttpClientManager.HttpClientManager(
ApplicationPaths,
LoggerFactory.CreateLogger<HttpClientManager.HttpClientManager>(),
FileSystemManager,
() => ApplicationUserAgent);
serviceCollection.AddSingleton(HttpClient);
serviceCollection.AddSingleton<IHttpClient, HttpClientManager.HttpClientManager>();
serviceCollection.AddSingleton(NetworkManager);
serviceCollection.AddSingleton(_networkManager);
IsoManager = new IsoManager();
serviceCollection.AddSingleton(IsoManager);
serviceCollection.AddSingleton<IIsoManager, IsoManager>();
TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LoggerFactory, FileSystemManager);
serviceCollection.AddSingleton(TaskManager);
serviceCollection.AddSingleton<ITaskManager, TaskManager>();
serviceCollection.AddSingleton(XmlSerializer);
serviceCollection.AddSingleton(_xmlSerializer);
serviceCollection.AddSingleton(typeof(IStreamHelper), typeof(StreamHelper));
serviceCollection.AddSingleton<IStreamHelper, StreamHelper>();
var cryptoProvider = new CryptographyProvider();
serviceCollection.AddSingleton<ICryptoProvider>(cryptoProvider);
serviceCollection.AddSingleton<ICryptoProvider, CryptographyProvider>();
SocketFactory = new SocketFactory();
serviceCollection.AddSingleton(SocketFactory);
serviceCollection.AddSingleton<ISocketFactory, SocketFactory>();
serviceCollection.AddSingleton(typeof(IInstallationManager), typeof(InstallationManager));
serviceCollection.AddSingleton<IInstallationManager, InstallationManager>();
serviceCollection.AddSingleton(typeof(IZipClient), typeof(ZipClient));
serviceCollection.AddSingleton<IZipClient, ZipClient>();
serviceCollection.AddSingleton(typeof(IHttpResultFactory), typeof(HttpResultFactory));
serviceCollection.AddSingleton<IHttpResultFactory, HttpResultFactory>();
serviceCollection.AddSingleton<IServerApplicationHost>(this);
serviceCollection.AddSingleton<IServerApplicationPaths>(ApplicationPaths);
serviceCollection.AddSingleton(ServerConfigurationManager);
LocalizationManager = new LocalizationManager(ServerConfigurationManager, JsonSerializer, LoggerFactory.CreateLogger<LocalizationManager>());
await LocalizationManager.LoadAll().ConfigureAwait(false);
serviceCollection.AddSingleton<ILocalizationManager>(LocalizationManager);
serviceCollection.AddSingleton<IBlurayExaminer>(new BdInfoExaminer(FileSystemManager));
serviceCollection.AddSingleton<ILocalizationManager, LocalizationManager>();
UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, () => UserManager);
serviceCollection.AddSingleton(UserDataManager);
serviceCollection.AddSingleton<IBlurayExaminer, BdInfoExaminer>();
_displayPreferencesRepository = new SqliteDisplayPreferencesRepository(
LoggerFactory.CreateLogger<SqliteDisplayPreferencesRepository>(),
ApplicationPaths,
FileSystemManager);
serviceCollection.AddSingleton<IDisplayPreferencesRepository>(_displayPreferencesRepository);
serviceCollection.AddSingleton<IUserDataRepository, SqliteUserDataRepository>();
serviceCollection.AddSingleton<IUserDataManager, UserDataManager>();
ItemRepository = new SqliteItemRepository(ServerConfigurationManager, this, LoggerFactory.CreateLogger<SqliteItemRepository>(), LocalizationManager);
serviceCollection.AddSingleton<IItemRepository>(ItemRepository);
serviceCollection.AddSingleton<IDisplayPreferencesRepository, SqliteDisplayPreferencesRepository>();
AuthenticationRepository = GetAuthenticationRepository();
serviceCollection.AddSingleton(AuthenticationRepository);
serviceCollection.AddSingleton<IItemRepository, SqliteItemRepository>();
_userRepository = GetUserRepository();
serviceCollection.AddSingleton<IAuthenticationRepository, AuthenticationRepository>();
UserManager = new UserManager(
LoggerFactory.CreateLogger<UserManager>(),
_userRepository,
XmlSerializer,
NetworkManager,
() => ImageProcessor,
() => DtoService,
this,
JsonSerializer,
FileSystemManager,
cryptoProvider);
serviceCollection.AddSingleton<IUserRepository, SqliteUserRepository>();
serviceCollection.AddSingleton(UserManager);
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
serviceCollection.AddTransient(provider => new Lazy<IDtoService>(provider.GetRequiredService<IDtoService>));
serviceCollection.AddSingleton<IUserManager, UserManager>();
MediaEncoder = new MediaBrowser.MediaEncoding.Encoder.MediaEncoder(
LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(),
ServerConfigurationManager,
FileSystemManager,
LocalizationManager,
() => SubtitleEncoder,
startupConfig,
StartupOptions.FFmpegPath);
serviceCollection.AddSingleton(MediaEncoder);
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
// TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation
serviceCollection.AddTransient(provider => new Lazy<EncodingHelper>(provider.GetRequiredService<EncodingHelper>));
serviceCollection.AddSingleton<IMediaEncoder>(provider =>
ActivatorUtilities.CreateInstance<MediaBrowser.MediaEncoding.Encoder.MediaEncoder>(provider, _startupOptions.FFmpegPath ?? string.Empty));
LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager, 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>();
var musicManager = new MusicManager(LibraryManager);
serviceCollection.AddSingleton<IMusicManager>(musicManager);
serviceCollection.AddSingleton<IMusicManager, MusicManager>();
LibraryMonitor = new LibraryMonitor(LoggerFactory, LibraryManager, ServerConfigurationManager, FileSystemManager);
serviceCollection.AddSingleton(LibraryMonitor);
serviceCollection.AddSingleton<ILibraryMonitor, LibraryMonitor>();
serviceCollection.AddSingleton<ISearchEngine>(new SearchEngine(LoggerFactory, LibraryManager, UserManager));
CertificateInfo = GetCertificateInfo(true);
Certificate = GetCertificate(CertificateInfo);
serviceCollection.AddSingleton<ISearchEngine, SearchEngine>();
serviceCollection.AddSingleton<ServiceController>();
serviceCollection.AddSingleton<IHttpListener, WebSocketSharpListener>();
serviceCollection.AddSingleton<IHttpServer, HttpListenerHost>();
ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger<ImageProcessor>(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => LibraryManager, () => MediaEncoder);
serviceCollection.AddSingleton(ImageProcessor);
TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager);
serviceCollection.AddSingleton(TVSeriesManager);
DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager);
serviceCollection.AddSingleton(DeviceManager);
MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder);
serviceCollection.AddSingleton(MediaSourceManager);
SubtitleManager = new SubtitleManager(LoggerFactory, FileSystemManager, LibraryMonitor, MediaSourceManager, LocalizationManager);
serviceCollection.AddSingleton(SubtitleManager);
ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LoggerFactory, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer);
serviceCollection.AddSingleton(ProviderManager);
DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ProviderManager, this, () => MediaSourceManager, () => LiveTvManager);
serviceCollection.AddSingleton(DtoService);
ChannelManager = new ChannelManager(
UserManager,
DtoService,
LibraryManager,
LoggerFactory.CreateLogger<ChannelManager>(),
ServerConfigurationManager,
FileSystemManager,
UserDataManager,
JsonSerializer,
ProviderManager);
serviceCollection.AddSingleton(ChannelManager);
SessionManager = new SessionManager(
LoggerFactory.CreateLogger<SessionManager>(),
UserDataManager,
LibraryManager,
UserManager,
musicManager,
DtoService,
ImageProcessor,
this,
AuthenticationRepository,
DeviceManager,
MediaSourceManager);
serviceCollection.AddSingleton(SessionManager);
serviceCollection.AddSingleton<IDlnaManager>(
new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this));
CollectionManager = new CollectionManager(LibraryManager, ApplicationPaths, LocalizationManager, FileSystemManager, LibraryMonitor, LoggerFactory, ProviderManager);
serviceCollection.AddSingleton(CollectionManager);
serviceCollection.AddSingleton(typeof(IPlaylistManager), typeof(PlaylistManager));
LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, LoggerFactory, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, FileSystemManager, () => ChannelManager);
serviceCollection.AddSingleton(LiveTvManager);
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager);
serviceCollection.AddSingleton(UserViewManager);
NotificationManager = new NotificationManager(
LoggerFactory.CreateLogger<NotificationManager>(),
UserManager,
ServerConfigurationManager);
serviceCollection.AddSingleton(NotificationManager);
serviceCollection.AddSingleton<IDeviceDiscovery>(new DeviceDiscovery(ServerConfigurationManager));
ChapterManager = new ChapterManager(ItemRepository);
serviceCollection.AddSingleton(ChapterManager);
EncodingManager = new MediaEncoder.EncodingManager(
LoggerFactory.CreateLogger<MediaEncoder.EncodingManager>(),
FileSystemManager,
MediaEncoder,
ChapterManager,
LibraryManager);
serviceCollection.AddSingleton(EncodingManager);
var activityLogRepo = GetActivityLogRepository();
serviceCollection.AddSingleton(activityLogRepo);
serviceCollection.AddSingleton<IActivityManager>(new ActivityManager(activityLogRepo, UserManager));
var authContext = new AuthorizationContext(AuthenticationRepository, UserManager);
serviceCollection.AddSingleton<IAuthorizationContext>(authContext);
serviceCollection.AddSingleton<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager));
AuthService = new AuthService(LoggerFactory.CreateLogger<AuthService>(), authContext, ServerConfigurationManager, SessionManager, NetworkManager);
serviceCollection.AddSingleton(AuthService);
SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder(
LibraryManager,
LoggerFactory.CreateLogger<MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder>(),
ApplicationPaths,
FileSystemManager,
MediaEncoder,
HttpClient,
MediaSourceManager);
serviceCollection.AddSingleton(SubtitleEncoder);
serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager));
serviceCollection.AddSingleton<EncodingHelper>();
serviceCollection.AddSingleton<IImageProcessor, ImageProcessor>();
serviceCollection.AddSingleton(typeof(IAttachmentExtractor), typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor));
serviceCollection.AddSingleton<ITVSeriesManager, TVSeriesManager>();
_displayPreferencesRepository.Initialize();
serviceCollection.AddSingleton<IDeviceManager, DeviceManager>();
var userDataRepo = new SqliteUserDataRepository(LoggerFactory.CreateLogger<SqliteUserDataRepository>(), ApplicationPaths);
serviceCollection.AddSingleton<IMediaSourceManager, MediaSourceManager>();
SetStaticProperties();
serviceCollection.AddSingleton<ISubtitleManager, SubtitleManager>();
serviceCollection.AddSingleton<IProviderManager, ProviderManager>();
// TODO: Refactor to eliminate the circular dependency here so that Lazy<T> isn't required
serviceCollection.AddTransient(provider => new Lazy<ILiveTvManager>(provider.GetRequiredService<ILiveTvManager>));
serviceCollection.AddSingleton<IDtoService, DtoService>();
serviceCollection.AddSingleton<IChannelManager, ChannelManager>();
serviceCollection.AddSingleton<ISessionManager, SessionManager>();
serviceCollection.AddSingleton<IDlnaManager, DlnaManager>();
serviceCollection.AddSingleton<ICollectionManager, CollectionManager>();
((UserManager)UserManager).Initialize();
serviceCollection.AddSingleton<IPlaylistManager, PlaylistManager>();
((UserDataManager)UserDataManager).Repository = userDataRepo;
ItemRepository.Initialize(userDataRepo, UserManager);
((LibraryManager)LibraryManager).ItemRepository = ItemRepository;
serviceCollection.AddSingleton<LiveTvDtoService>();
serviceCollection.AddSingleton<ILiveTvManager, LiveTvManager>();
serviceCollection.AddSingleton<IUserViewManager, UserViewManager>();
serviceCollection.AddSingleton<INotificationManager, NotificationManager>();
serviceCollection.AddSingleton<IDeviceDiscovery, DeviceDiscovery>();
serviceCollection.AddSingleton<IChapterManager, ChapterManager>();
serviceCollection.AddSingleton<IEncodingManager, MediaEncoder.EncodingManager>();
serviceCollection.AddSingleton<IActivityRepository, ActivityRepository>();
serviceCollection.AddSingleton<IActivityManager, ActivityManager>();
serviceCollection.AddSingleton<IAuthorizationContext, AuthorizationContext>();
serviceCollection.AddSingleton<ISessionContext, SessionContext>();
serviceCollection.AddSingleton<IAuthService, AuthService>();
serviceCollection.AddSingleton<ISubtitleEncoder, MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder>();
serviceCollection.AddSingleton<IResourceFileManager, ResourceFileManager>();
serviceCollection.AddSingleton<EncodingHelper>();
serviceCollection.AddSingleton<IAttachmentExtractor, MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor>();
}
/// <summary>
/// Create services registered with the service container that need to be initialized at application startup.
/// </summary>
public void InitializeServices()
/// <returns>A task representing the service initialization operation.</returns>
public async Task InitializeServices()
{
HttpServer = Resolve<IHttpServer>();
var localizationManager = (LocalizationManager)Resolve<ILocalizationManager>();
await localizationManager.LoadAll().ConfigureAwait(false);
_mediaEncoder = Resolve<IMediaEncoder>();
_sessionManager = Resolve<ISessionManager>();
_httpServer = Resolve<IHttpServer>();
_httpClient = Resolve<IHttpClient>();
((SqliteDisplayPreferencesRepository)Resolve<IDisplayPreferencesRepository>()).Initialize();
((AuthenticationRepository)Resolve<IAuthenticationRepository>()).Initialize();
((SqliteUserRepository)Resolve<IUserRepository>()).Initialize();
((ActivityRepository)Resolve<IActivityRepository>()).Initialize();
SetStaticProperties();
var userManager = (UserManager)Resolve<IUserManager>();
userManager.Initialize();
var userDataRepo = (SqliteUserDataRepository)Resolve<IUserDataRepository>();
((SqliteItemRepository)Resolve<IItemRepository>()).Initialize(userDataRepo, userManager);
FindParts();
}
public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths)
@ -940,75 +768,38 @@ namespace Emby.Server.Implementations
}
}
/// <summary>
/// Gets the user repository.
/// </summary>
/// <returns><see cref="Task{SqliteUserRepository}" />.</returns>
private SqliteUserRepository GetUserRepository()
{
var repo = new SqliteUserRepository(
LoggerFactory.CreateLogger<SqliteUserRepository>(),
ApplicationPaths);
repo.Initialize();
return repo;
}
private IAuthenticationRepository GetAuthenticationRepository()
{
var repo = new AuthenticationRepository(LoggerFactory, ServerConfigurationManager);
repo.Initialize();
return repo;
}
private IActivityRepository GetActivityLogRepository()
{
var repo = new ActivityRepository(LoggerFactory.CreateLogger<ActivityRepository>(), ServerConfigurationManager.ApplicationPaths, FileSystemManager);
repo.Initialize();
return repo;
}
/// <summary>
/// Dirty hacks.
/// </summary>
private void SetStaticProperties()
{
ItemRepository.ImageProcessor = ImageProcessor;
// For now there's no real way to inject these properly
BaseItem.Logger = LoggerFactory.CreateLogger("BaseItem");
BaseItem.Logger = Resolve<ILogger<BaseItem>>();
BaseItem.ConfigurationManager = ServerConfigurationManager;
BaseItem.LibraryManager = LibraryManager;
BaseItem.ProviderManager = ProviderManager;
BaseItem.LocalizationManager = LocalizationManager;
BaseItem.ItemRepository = ItemRepository;
User.UserManager = UserManager;
BaseItem.FileSystem = FileSystemManager;
BaseItem.UserDataManager = UserDataManager;
BaseItem.ChannelManager = ChannelManager;
Video.LiveTvManager = LiveTvManager;
Folder.UserViewManager = UserViewManager;
UserView.TVSeriesManager = TVSeriesManager;
UserView.CollectionManager = CollectionManager;
BaseItem.MediaSourceManager = MediaSourceManager;
CollectionFolder.XmlSerializer = XmlSerializer;
CollectionFolder.JsonSerializer = JsonSerializer;
BaseItem.LibraryManager = Resolve<ILibraryManager>();
BaseItem.ProviderManager = Resolve<IProviderManager>();
BaseItem.LocalizationManager = Resolve<ILocalizationManager>();
BaseItem.ItemRepository = Resolve<IItemRepository>();
User.UserManager = Resolve<IUserManager>();
BaseItem.FileSystem = _fileSystemManager;
BaseItem.UserDataManager = Resolve<IUserDataManager>();
BaseItem.ChannelManager = Resolve<IChannelManager>();
Video.LiveTvManager = Resolve<ILiveTvManager>();
Folder.UserViewManager = Resolve<IUserViewManager>();
UserView.TVSeriesManager = Resolve<ITVSeriesManager>();
UserView.CollectionManager = Resolve<ICollectionManager>();
BaseItem.MediaSourceManager = Resolve<IMediaSourceManager>();
CollectionFolder.XmlSerializer = _xmlSerializer;
CollectionFolder.JsonSerializer = Resolve<IJsonSerializer>();
CollectionFolder.ApplicationHost = this;
AuthenticatedAttribute.AuthService = AuthService;
AuthenticatedAttribute.AuthService = Resolve<IAuthService>();
}
/// <summary>
/// Finds the parts.
/// Finds plugin components and register them with the appropriate services.
/// </summary>
public void FindParts()
private void FindParts()
{
InstallationManager = ServiceProvider.GetService<IInstallationManager>();
if (!ServerConfigurationManager.Configuration.IsPortAuthorized)
{
ServerConfigurationManager.Configuration.IsPortAuthorized = true;
@ -1021,34 +812,34 @@ namespace Emby.Server.Implementations
.Where(i => i != null)
.ToArray();
HttpServer.Init(GetExportTypes<IService>(), GetExports<IWebSocketListener>(), GetUrlPrefixes());
_httpServer.Init(GetExportTypes<IService>(), GetExports<IWebSocketListener>(), GetUrlPrefixes());
LibraryManager.AddParts(
Resolve<ILibraryManager>().AddParts(
GetExports<IResolverIgnoreRule>(),
GetExports<IItemResolver>(),
GetExports<IIntroProvider>(),
GetExports<IBaseItemComparer>(),
GetExports<ILibraryPostScanTask>());
ProviderManager.AddParts(
Resolve<IProviderManager>().AddParts(
GetExports<IImageProvider>(),
GetExports<IMetadataService>(),
GetExports<IMetadataProvider>(),
GetExports<IMetadataSaver>(),
GetExports<IExternalId>());
LiveTvManager.AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
Resolve<ILiveTvManager>().AddParts(GetExports<ILiveTvService>(), GetExports<ITunerHost>(), GetExports<IListingsProvider>());
SubtitleManager.AddParts(GetExports<ISubtitleProvider>());
Resolve<ISubtitleManager>().AddParts(GetExports<ISubtitleProvider>());
ChannelManager.AddParts(GetExports<IChannel>());
Resolve<IChannelManager>().AddParts(GetExports<IChannel>());
MediaSourceManager.AddParts(GetExports<IMediaSourceProvider>());
Resolve<IMediaSourceManager>().AddParts(GetExports<IMediaSourceProvider>());
NotificationManager.AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
UserManager.AddParts(GetExports<IAuthenticationProvider>(), GetExports<IPasswordResetProvider>());
Resolve<INotificationManager>().AddParts(GetExports<INotificationService>(), GetExports<INotificationTypeFactory>());
Resolve<IUserManager>().AddParts(GetExports<IAuthenticationProvider>(), GetExports<IPasswordResetProvider>());
IsoManager.AddParts(GetExports<IIsoMounter>());
Resolve<IIsoManager>().AddParts(GetExports<IIsoMounter>());
}
private IPlugin LoadPlugin(IPlugin plugin)
@ -1155,16 +946,6 @@ namespace Emby.Server.Implementations
});
}
private CertificateInfo GetCertificateInfo(bool generateCertificate)
{
// Custom cert
return new CertificateInfo
{
Path = ServerConfigurationManager.Configuration.CertificatePath,
Password = ServerConfigurationManager.Configuration.CertificatePassword
};
}
/// <summary>
/// Called when [configuration updated].
/// </summary>
@ -1191,14 +972,13 @@ namespace Emby.Server.Implementations
}
}
if (!HttpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase))
if (!_httpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase))
{
requiresRestart = true;
}
var currentCertPath = CertificateInfo?.Path;
var newCertInfo = GetCertificateInfo(false);
var newCertPath = newCertInfo?.Path;
var newCertPath = ServerConfigurationManager.Configuration.CertificatePath;
if (!string.Equals(currentCertPath, newCertPath, StringComparison.OrdinalIgnoreCase))
{
@ -1251,7 +1031,7 @@ namespace Emby.Server.Implementations
{
try
{
await SessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false);
await _sessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false);
}
catch (Exception ex)
{
@ -1355,7 +1135,7 @@ namespace Emby.Server.Implementations
IsShuttingDown = IsShuttingDown,
Version = ApplicationVersionString,
WebSocketPortNumber = HttpPort,
CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(),
CompletedInstallations = Resolve<IInstallationManager>().CompletedInstallations.ToArray(),
Id = SystemId,
ProgramDataPath = ApplicationPaths.ProgramDataPath,
WebPath = ApplicationPaths.WebPath,
@ -1375,14 +1155,14 @@ namespace Emby.Server.Implementations
ServerName = FriendlyName,
LocalAddress = localAddress,
SupportsLibraryMonitor = true,
EncoderLocation = MediaEncoder.EncoderLocation,
EncoderLocation = _mediaEncoder.EncoderLocation,
SystemArchitecture = RuntimeInformation.OSArchitecture,
PackageName = StartupOptions.PackageName
PackageName = _startupOptions.PackageName
};
}
public IEnumerable<WakeOnLanInfo> GetWakeOnLanInfo()
=> NetworkManager.GetMacAddresses()
=> _networkManager.GetMacAddresses()
.Select(i => new WakeOnLanInfo(i))
.ToList();
@ -1494,7 +1274,7 @@ namespace Emby.Server.Implementations
if (addresses.Count == 0)
{
addresses.AddRange(NetworkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces));
addresses.AddRange(_networkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces));
}
var resultList = new List<IPAddress>();
@ -1561,7 +1341,7 @@ namespace Emby.Server.Implementations
try
{
using (var response = await HttpClient.SendAsync(
using (var response = await _httpClient.SendAsync(
new HttpRequestOptions
{
Url = apiUrl,
@ -1614,7 +1394,7 @@ namespace Emby.Server.Implementations
try
{
await SessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false);
await _sessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false);
}
catch (Exception ex)
{
@ -1735,14 +1515,8 @@ namespace Emby.Server.Implementations
Logger.LogError(ex, "Error disposing {Type}", part.GetType().Name);
}
}
_userRepository?.Dispose();
_displayPreferencesRepository?.Dispose();
}
_userRepository = null;
_displayPreferencesRepository = null;
_disposed = true;
}
}

@ -39,12 +39,11 @@ namespace Emby.Server.Implementations.Data
{
private const string ChaptersTableName = "Chapters2";
/// <summary>
/// The _app paths
/// </summary>
private readonly IServerConfigurationManager _config;
private readonly IServerApplicationHost _appHost;
private readonly ILocalizationManager _localization;
// TODO: Remove this dependency. GetImageCacheTag() is the only method used and it can be converted to a static helper method
private readonly IImageProcessor _imageProcessor;
private readonly TypeMapper _typeMapper;
private readonly JsonSerializerOptions _jsonOptions;
@ -71,7 +70,8 @@ namespace Emby.Server.Implementations.Data
IServerConfigurationManager config,
IServerApplicationHost appHost,
ILogger<SqliteItemRepository> logger,
ILocalizationManager localization)
ILocalizationManager localization,
IImageProcessor imageProcessor)
: base(logger)
{
if (config == null)
@ -82,6 +82,7 @@ namespace Emby.Server.Implementations.Data
_config = config;
_appHost = appHost;
_localization = localization;
_imageProcessor = imageProcessor;
_typeMapper = new TypeMapper();
_jsonOptions = JsonDefaults.GetOptions();
@ -98,8 +99,6 @@ namespace Emby.Server.Implementations.Data
/// <inheritdoc />
protected override TempStoreMode TempStore => TempStoreMode.Memory;
public IImageProcessor ImageProcessor { get; set; }
/// <summary>
/// Opens the connection to the database
/// </summary>
@ -1991,7 +1990,7 @@ namespace Emby.Server.Implementations.Data
if (!string.IsNullOrEmpty(chapter.ImagePath))
{
chapter.ImageTag = ImageProcessor.GetImageCacheTag(item, chapter);
chapter.ImageTag = _imageProcessor.GetImageCacheTag(item, chapter);
}
}

@ -38,10 +38,11 @@ namespace Emby.Server.Implementations.Devices
private readonly IServerConfigurationManager _config;
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localizationManager;
private readonly IAuthenticationRepository _authRepo;
private readonly Dictionary<string, ClientCapabilities> _capabilitiesCache;
public event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
public event EventHandler<GenericEventArgs<CameraImageUploadInfo>> CameraImageUploaded;
private readonly object _cameraUploadSyncLock = new object();
@ -65,10 +66,9 @@ namespace Emby.Server.Implementations.Devices
_libraryManager = libraryManager;
_localizationManager = localizationManager;
_authRepo = authRepo;
_capabilitiesCache = new Dictionary<string, ClientCapabilities>(StringComparer.OrdinalIgnoreCase);
}
private Dictionary<string, ClientCapabilities> _capabilitiesCache = new Dictionary<string, ClientCapabilities>(StringComparer.OrdinalIgnoreCase);
public void SaveCapabilities(string deviceId, ClientCapabilities capabilities)
{
var path = Path.Combine(GetDevicePath(deviceId), "capabilities.json");

@ -38,21 +38,23 @@ namespace Emby.Server.Implementations.Dto
private readonly IProviderManager _providerManager;
private readonly IApplicationHost _appHost;
private readonly Func<IMediaSourceManager> _mediaSourceManager;
private readonly Func<ILiveTvManager> _livetvManager;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly Lazy<ILiveTvManager> _livetvManagerFactory;
private ILiveTvManager LivetvManager => _livetvManagerFactory.Value;
public DtoService(
ILoggerFactory loggerFactory,
ILogger<DtoService> logger,
ILibraryManager libraryManager,
IUserDataManager userDataRepository,
IItemRepository itemRepo,
IImageProcessor imageProcessor,
IProviderManager providerManager,
IApplicationHost appHost,
Func<IMediaSourceManager> mediaSourceManager,
Func<ILiveTvManager> livetvManager)
IMediaSourceManager mediaSourceManager,
Lazy<ILiveTvManager> livetvManagerFactory)
{
_logger = loggerFactory.CreateLogger(nameof(DtoService));
_logger = logger;
_libraryManager = libraryManager;
_userDataRepository = userDataRepository;
_itemRepo = itemRepo;
@ -60,7 +62,7 @@ namespace Emby.Server.Implementations.Dto
_providerManager = providerManager;
_appHost = appHost;
_mediaSourceManager = mediaSourceManager;
_livetvManager = livetvManager;
_livetvManagerFactory = livetvManagerFactory;
}
/// <summary>
@ -125,12 +127,12 @@ namespace Emby.Server.Implementations.Dto
if (programTuples.Count > 0)
{
_livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult();
LivetvManager.AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult();
}
if (channelTuples.Count > 0)
{
_livetvManager().AddChannelInfo(channelTuples, options, user);
LivetvManager.AddChannelInfo(channelTuples, options, user);
}
return returnItems;
@ -142,12 +144,12 @@ namespace Emby.Server.Implementations.Dto
if (item is LiveTvChannel tvChannel)
{
var list = new List<(BaseItemDto, LiveTvChannel)>(1) { (dto, tvChannel) };
_livetvManager().AddChannelInfo(list, options, user);
LivetvManager.AddChannelInfo(list, options, user);
}
else if (item is LiveTvProgram)
{
var list = new List<(BaseItem, BaseItemDto)>(1) { (item, dto) };
var task = _livetvManager().AddInfoToProgramDto(list, options.Fields, user);
var task = LivetvManager.AddInfoToProgramDto(list, options.Fields, user);
Task.WaitAll(task);
}
@ -223,7 +225,7 @@ namespace Emby.Server.Implementations.Dto
if (item is IHasMediaSources
&& options.ContainsField(ItemFields.MediaSources))
{
dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(item, true, user).ToArray();
dto.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, true, user).ToArray();
NormalizeMediaSourceContainers(dto);
}
@ -254,7 +256,7 @@ namespace Emby.Server.Implementations.Dto
dto.Etag = item.GetEtag(user);
}
var liveTvManager = _livetvManager();
var liveTvManager = LivetvManager;
var activeRecording = liveTvManager.GetActiveRecordingInfo(item.Path);
if (activeRecording != null)
{
@ -1045,7 +1047,7 @@ namespace Emby.Server.Implementations.Dto
}
else
{
mediaStreams = _mediaSourceManager().GetStaticMediaSources(item, true)[0].MediaStreams.ToArray();
mediaStreams = _mediaSourceManager.GetStaticMediaSources(item, true)[0].MediaStreams.ToArray();
}
dto.MediaStreams = mediaStreams;

@ -16,17 +16,25 @@ namespace Emby.Server.Implementations.EntryPoints
private readonly IServerApplicationHost _appHost;
private readonly IConfiguration _appConfig;
private readonly IServerConfigurationManager _config;
private readonly IStartupOptions _startupOptions;
/// <summary>
/// Initializes a new instance of the <see cref="StartupWizard"/> class.
/// </summary>
/// <param name="appHost">The application host.</param>
/// <param name="appConfig">The application configuration.</param>
/// <param name="config">The configuration manager.</param>
public StartupWizard(IServerApplicationHost appHost, IConfiguration appConfig, IServerConfigurationManager config)
/// <param name="startupOptions">The application startup options.</param>
public StartupWizard(
IServerApplicationHost appHost,
IConfiguration appConfig,
IServerConfigurationManager config,
IStartupOptions startupOptions)
{
_appHost = appHost;
_appConfig = appConfig;
_config = config;
_startupOptions = startupOptions;
}
/// <inheritdoc />
@ -51,8 +59,7 @@ namespace Emby.Server.Implementations.EntryPoints
}
// Do nothing if the web app is configured to not run automatically
var options = ((ApplicationHost)_appHost).StartupOptions;
if (!_config.Configuration.AutoRunWebApp || options.NoAutoRunWebApp)
if (!_config.Configuration.AutoRunWebApp || _startupOptions.NoAutoRunWebApp)
{
return;
}

@ -6,6 +6,7 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using MediaBrowser.Common;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
@ -24,7 +25,7 @@ namespace Emby.Server.Implementations.HttpClientManager
private readonly ILogger _logger;
private readonly IApplicationPaths _appPaths;
private readonly IFileSystem _fileSystem;
private readonly Func<string> _defaultUserAgentFn;
private readonly IApplicationHost _appHost;
/// <summary>
/// Holds a dictionary of http clients by host. Use GetHttpClient(host) to retrieve or create a client for web requests.
@ -40,12 +41,12 @@ namespace Emby.Server.Implementations.HttpClientManager
IApplicationPaths appPaths,
ILogger<HttpClientManager> logger,
IFileSystem fileSystem,
Func<string> defaultUserAgentFn)
IApplicationHost appHost)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_fileSystem = fileSystem;
_appPaths = appPaths ?? throw new ArgumentNullException(nameof(appPaths));
_defaultUserAgentFn = defaultUserAgentFn;
_appHost = appHost;
}
/// <summary>
@ -91,7 +92,7 @@ namespace Emby.Server.Implementations.HttpClientManager
if (options.EnableDefaultUserAgent
&& !request.Headers.TryGetValues(HeaderNames.UserAgent, out _))
{
request.Headers.Add(HeaderNames.UserAgent, _defaultUserAgentFn());
request.Headers.Add(HeaderNames.UserAgent, _appHost.ApplicationUserAgent);
}
switch (options.DecompressionMethod)

@ -17,6 +17,11 @@ namespace Emby.Server.Implementations.IO
{
public class LibraryMonitor : ILibraryMonitor
{
private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager;
private readonly IServerConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
/// <summary>
/// The file system watchers.
/// </summary>
@ -113,34 +118,23 @@ namespace Emby.Server.Implementations.IO
}
catch (Exception ex)
{
Logger.LogError(ex, "Error in ReportFileSystemChanged for {path}", path);
_logger.LogError(ex, "Error in ReportFileSystemChanged for {path}", path);
}
}
}
/// <summary>
/// Gets or sets the logger.
/// </summary>
/// <value>The logger.</value>
private ILogger Logger { get; set; }
private ILibraryManager LibraryManager { get; set; }
private IServerConfigurationManager ConfigurationManager { get; set; }
private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="LibraryMonitor" /> class.
/// </summary>
public LibraryMonitor(
ILoggerFactory loggerFactory,
ILogger<LibraryMonitor> logger,
ILibraryManager libraryManager,
IServerConfigurationManager configurationManager,
IFileSystem fileSystem)
{
LibraryManager = libraryManager;
Logger = loggerFactory.CreateLogger(GetType().Name);
ConfigurationManager = configurationManager;
_libraryManager = libraryManager;
_logger = logger;
_configurationManager = configurationManager;
_fileSystem = fileSystem;
}
@ -151,7 +145,7 @@ namespace Emby.Server.Implementations.IO
return false;
}
var options = LibraryManager.GetLibraryOptions(item);
var options = _libraryManager.GetLibraryOptions(item);
if (options != null)
{
@ -163,12 +157,12 @@ namespace Emby.Server.Implementations.IO
public void Start()
{
LibraryManager.ItemAdded += OnLibraryManagerItemAdded;
LibraryManager.ItemRemoved += OnLibraryManagerItemRemoved;
_libraryManager.ItemAdded += OnLibraryManagerItemAdded;
_libraryManager.ItemRemoved += OnLibraryManagerItemRemoved;
var pathsToWatch = new List<string>();
var paths = LibraryManager
var paths = _libraryManager
.RootFolder
.Children
.Where(IsLibraryMonitorEnabled)
@ -261,7 +255,7 @@ namespace Emby.Server.Implementations.IO
if (!Directory.Exists(path))
{
// Seeing a crash in the mono runtime due to an exception being thrown on a different thread
Logger.LogInformation("Skipping realtime monitor for {Path} because the path does not exist", path);
_logger.LogInformation("Skipping realtime monitor for {Path} because the path does not exist", path);
return;
}
@ -297,7 +291,7 @@ namespace Emby.Server.Implementations.IO
if (_fileSystemWatchers.TryAdd(path, newWatcher))
{
newWatcher.EnableRaisingEvents = true;
Logger.LogInformation("Watching directory " + path);
_logger.LogInformation("Watching directory " + path);
}
else
{
@ -307,7 +301,7 @@ namespace Emby.Server.Implementations.IO
}
catch (Exception ex)
{
Logger.LogError(ex, "Error watching path: {path}", path);
_logger.LogError(ex, "Error watching path: {path}", path);
}
});
}
@ -333,7 +327,7 @@ namespace Emby.Server.Implementations.IO
{
using (watcher)
{
Logger.LogInformation("Stopping directory watching for path {Path}", watcher.Path);
_logger.LogInformation("Stopping directory watching for path {Path}", watcher.Path);
watcher.Created -= OnWatcherChanged;
watcher.Deleted -= OnWatcherChanged;
@ -372,7 +366,7 @@ namespace Emby.Server.Implementations.IO
var ex = e.GetException();
var dw = (FileSystemWatcher)sender;
Logger.LogError(ex, "Error in Directory watcher for: {Path}", dw.Path);
_logger.LogError(ex, "Error in Directory watcher for: {Path}", dw.Path);
DisposeWatcher(dw, true);
}
@ -390,7 +384,7 @@ namespace Emby.Server.Implementations.IO
}
catch (Exception ex)
{
Logger.LogError(ex, "Exception in ReportFileSystemChanged. Path: {FullPath}", e.FullPath);
_logger.LogError(ex, "Exception in ReportFileSystemChanged. Path: {FullPath}", e.FullPath);
}
}
@ -416,13 +410,13 @@ namespace Emby.Server.Implementations.IO
{
if (_fileSystem.AreEqual(i, path))
{
Logger.LogDebug("Ignoring change to {Path}", path);
_logger.LogDebug("Ignoring change to {Path}", path);
return true;
}
if (_fileSystem.ContainsSubPath(i, path))
{
Logger.LogDebug("Ignoring change to {Path}", path);
_logger.LogDebug("Ignoring change to {Path}", path);
return true;
}
@ -430,7 +424,7 @@ namespace Emby.Server.Implementations.IO
var parent = Path.GetDirectoryName(i);
if (!string.IsNullOrEmpty(parent) && _fileSystem.AreEqual(parent, path))
{
Logger.LogDebug("Ignoring change to {Path}", path);
_logger.LogDebug("Ignoring change to {Path}", path);
return true;
}
@ -485,7 +479,7 @@ namespace Emby.Server.Implementations.IO
}
}
var newRefresher = new FileRefresher(path, ConfigurationManager, LibraryManager, Logger);
var newRefresher = new FileRefresher(path, _configurationManager, _libraryManager, _logger);
newRefresher.Completed += NewRefresher_Completed;
_activeRefreshers.Add(newRefresher);
}
@ -502,8 +496,8 @@ namespace Emby.Server.Implementations.IO
/// </summary>
public void Stop()
{
LibraryManager.ItemAdded -= OnLibraryManagerItemAdded;
LibraryManager.ItemRemoved -= OnLibraryManagerItemRemoved;
_libraryManager.ItemAdded -= OnLibraryManagerItemAdded;
_libraryManager.ItemRemoved -= OnLibraryManagerItemRemoved;
foreach (var watcher in _fileSystemWatchers.Values.ToList())
{

@ -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);
_itemRepository.DeleteItem(item.Id);
foreach (var child in children)
{
ItemRepository.DeleteItem(child.Id);
_itemRepository.DeleteItem(child.Id);
}
_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))
{
@ -2675,8 +2646,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))
{
@ -2687,7 +2658,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))
{
@ -2756,7 +2727,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)
@ -2779,7 +2750,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
{
@ -2796,7 +2767,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)
@ -2806,7 +2777,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)
@ -2817,7 +2788,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);
@ -2850,7 +2821,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))
@ -2869,7 +2840,7 @@ namespace Emby.Server.Implementations.Library
}
}
_libraryMonitorFactory().Stop();
LibraryMonitor.Stop();
try
{
@ -2904,7 +2875,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();
}
}
}
@ -2964,7 +2935,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);
@ -3007,7 +2978,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);
@ -3060,7 +3031,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);
@ -3069,7 +3040,7 @@ namespace Emby.Server.Implementations.Library
throw new FileNotFoundException("The media folder does not exist");
}
_libraryMonitorFactory().Stop();
LibraryMonitor.Stop();
try
{
@ -3089,7 +3060,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();
}
}
}
@ -3103,7 +3074,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))
{
@ -3118,11 +3089,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();
.ToArray();
ConfigurationManager.SaveConfiguration();
_configurationManager.SaveConfiguration();
}
}
@ -3133,7 +3104,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))

@ -33,13 +33,13 @@ namespace Emby.Server.Implementations.Library
private readonly ILibraryManager _libraryManager;
private readonly IJsonSerializer _jsonSerializer;
private readonly IFileSystem _fileSystem;
private IMediaSourceProvider[] _providers;
private readonly ILogger _logger;
private readonly IUserDataManager _userDataManager;
private readonly Func<IMediaEncoder> _mediaEncoder;
private ILocalizationManager _localizationManager;
private IApplicationPaths _appPaths;
private readonly IMediaEncoder _mediaEncoder;
private readonly ILocalizationManager _localizationManager;
private readonly IApplicationPaths _appPaths;
private IMediaSourceProvider[] _providers;
public MediaSourceManager(
IItemRepository itemRepo,
@ -47,16 +47,16 @@ namespace Emby.Server.Implementations.Library
ILocalizationManager localizationManager,
IUserManager userManager,
ILibraryManager libraryManager,
ILoggerFactory loggerFactory,
ILogger<MediaSourceManager> logger,
IJsonSerializer jsonSerializer,
IFileSystem fileSystem,
IUserDataManager userDataManager,
Func<IMediaEncoder> mediaEncoder)
IMediaEncoder mediaEncoder)
{
_itemRepo = itemRepo;
_userManager = userManager;
_libraryManager = libraryManager;
_logger = loggerFactory.CreateLogger(nameof(MediaSourceManager));
_logger = logger;
_jsonSerializer = jsonSerializer;
_fileSystem = fileSystem;
_userDataManager = userDataManager;
@ -496,7 +496,7 @@ namespace Emby.Server.Implementations.Library
// hack - these two values were taken from LiveTVMediaSourceProvider
string cacheKey = request.OpenToken;
await new LiveStreamHelper(_mediaEncoder(), _logger, _jsonSerializer, _appPaths)
await new LiveStreamHelper(_mediaEncoder, _logger, _jsonSerializer, _appPaths)
.AddMediaInfoWithProbe(mediaSource, isAudio, cacheKey, true, cancellationToken)
.ConfigureAwait(false);
}
@ -621,7 +621,7 @@ namespace Emby.Server.Implementations.Library
if (liveStreamInfo is IDirectStreamProvider)
{
var info = await _mediaEncoder().GetMediaInfo(new MediaInfoRequest
var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
{
MediaSource = mediaSource,
ExtractChapters = false,
@ -674,7 +674,7 @@ namespace Emby.Server.Implementations.Library
mediaSource.AnalyzeDurationMs = 3000;
}
mediaInfo = await _mediaEncoder().GetMediaInfo(new MediaInfoRequest
mediaInfo = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
{
MediaSource = mediaSource,
MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,

@ -17,16 +17,15 @@ namespace Emby.Server.Implementations.Library
{
public class SearchEngine : ISearchEngine
{
private readonly ILogger _logger;
private readonly ILibraryManager _libraryManager;
private readonly IUserManager _userManager;
private readonly ILogger _logger;
public SearchEngine(ILoggerFactory loggerFactory, ILibraryManager libraryManager, IUserManager userManager)
public SearchEngine(ILogger<SearchEngine> logger, ILibraryManager libraryManager, IUserManager userManager)
{
_logger = logger;
_libraryManager = libraryManager;
_userManager = userManager;
_logger = loggerFactory.CreateLogger("SearchEngine");
}
public QueryResult<SearchHintInfo> GetSearchHints(SearchQuery query)

@ -28,25 +28,24 @@ namespace Emby.Server.Implementations.Library
private readonly ILogger _logger;
private readonly IServerConfigurationManager _config;
private Func<IUserManager> _userManager;
public UserDataManager(ILoggerFactory loggerFactory, IServerConfigurationManager config, Func<IUserManager> userManager)
private readonly IUserManager _userManager;
private readonly IUserDataRepository _repository;
public UserDataManager(
ILogger<UserDataManager> logger,
IServerConfigurationManager config,
IUserManager userManager,
IUserDataRepository repository)
{
_logger = logger;
_config = config;
_logger = loggerFactory.CreateLogger(GetType().Name);
_userManager = userManager;
_repository = repository;
}
/// <summary>
/// Gets or sets the repository.
/// </summary>
/// <value>The repository.</value>
public IUserDataRepository Repository { get; set; }
public void SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
{
var user = _userManager().GetUserById(userId);
var user = _userManager.GetUserById(userId);
SaveUserData(user, item, userData, reason, cancellationToken);
}
@ -71,7 +70,7 @@ namespace Emby.Server.Implementations.Library
foreach (var key in keys)
{
Repository.SaveUserData(userId, key, userData, cancellationToken);
_repository.SaveUserData(userId, key, userData, cancellationToken);
}
var cacheKey = GetCacheKey(userId, item.Id);
@ -96,9 +95,9 @@ namespace Emby.Server.Implementations.Library
/// <returns></returns>
public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken)
{
var user = _userManager().GetUserById(userId);
var user = _userManager.GetUserById(userId);
Repository.SaveAllUserData(user.InternalId, userData, cancellationToken);
_repository.SaveAllUserData(user.InternalId, userData, cancellationToken);
}
/// <summary>
@ -108,14 +107,14 @@ namespace Emby.Server.Implementations.Library
/// <returns></returns>
public List<UserItemData> GetAllUserData(Guid userId)
{
var user = _userManager().GetUserById(userId);
var user = _userManager.GetUserById(userId);
return Repository.GetAllUserData(user.InternalId);
return _repository.GetAllUserData(user.InternalId);
}
public UserItemData GetUserData(Guid userId, Guid itemId, List<string> keys)
{
var user = _userManager().GetUserById(userId);
var user = _userManager.GetUserById(userId);
return GetUserData(user, itemId, keys);
}
@ -131,7 +130,7 @@ namespace Emby.Server.Implementations.Library
private UserItemData GetUserDataInternal(long internalUserId, List<string> keys)
{
var userData = Repository.GetUserData(internalUserId, keys);
var userData = _repository.GetUserData(internalUserId, keys);
if (userData != null)
{

@ -44,22 +44,14 @@ namespace Emby.Server.Implementations.Library
{
private readonly object _policySyncLock = new object();
private readonly object _configSyncLock = new object();
/// <summary>
/// The logger.
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// Gets the active user repository.
/// </summary>
/// <value>The user repository.</value>
private readonly ILogger _logger;
private readonly IUserRepository _userRepository;
private readonly IXmlSerializer _xmlSerializer;
private readonly IJsonSerializer _jsonSerializer;
private readonly INetworkManager _networkManager;
private readonly Func<IImageProcessor> _imageProcessorFactory;
private readonly Func<IDtoService> _dtoServiceFactory;
private readonly IImageProcessor _imageProcessor;
private readonly Lazy<IDtoService> _dtoServiceFactory;
private readonly IServerApplicationHost _appHost;
private readonly IFileSystem _fileSystem;
private readonly ICryptoProvider _cryptoProvider;
@ -74,13 +66,15 @@ namespace Emby.Server.Implementations.Library
private IPasswordResetProvider[] _passwordResetProviders;
private DefaultPasswordResetProvider _defaultPasswordResetProvider;
private IDtoService DtoService => _dtoServiceFactory.Value;
public UserManager(
ILogger<UserManager> logger,
IUserRepository userRepository,
IXmlSerializer xmlSerializer,
INetworkManager networkManager,
Func<IImageProcessor> imageProcessorFactory,
Func<IDtoService> dtoServiceFactory,
IImageProcessor imageProcessor,
Lazy<IDtoService> dtoServiceFactory,
IServerApplicationHost appHost,
IJsonSerializer jsonSerializer,
IFileSystem fileSystem,
@ -90,7 +84,7 @@ namespace Emby.Server.Implementations.Library
_userRepository = userRepository;
_xmlSerializer = xmlSerializer;
_networkManager = networkManager;
_imageProcessorFactory = imageProcessorFactory;
_imageProcessor = imageProcessor;
_dtoServiceFactory = dtoServiceFactory;
_appHost = appHost;
_jsonSerializer = jsonSerializer;
@ -605,7 +599,7 @@ namespace Emby.Server.Implementations.Library
try
{
_dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user);
DtoService.AttachPrimaryImageAspectRatio(dto, user);
}
catch (Exception ex)
{
@ -630,7 +624,7 @@ namespace Emby.Server.Implementations.Library
{
try
{
return _imageProcessorFactory().GetImageCacheTag(item, image);
return _imageProcessor.GetImageCacheTag(item, image);
}
catch (Exception ex)
{

@ -28,7 +28,6 @@ namespace Emby.Server.Implementations.LiveTv
private readonly ILogger _logger;
private readonly IImageProcessor _imageProcessor;
private readonly IDtoService _dtoService;
private readonly IApplicationHost _appHost;
private readonly ILibraryManager _libraryManager;

@ -49,29 +49,24 @@ namespace Emby.Server.Implementations.LiveTv
private readonly ILogger _logger;
private readonly IItemRepository _itemRepo;
private readonly IUserManager _userManager;
private readonly IDtoService _dtoService;
private readonly IUserDataManager _userDataManager;
private readonly ILibraryManager _libraryManager;
private readonly ITaskManager _taskManager;
private readonly IJsonSerializer _jsonSerializer;
private readonly Func<IChannelManager> _channelManager;
private readonly IDtoService _dtoService;
private readonly ILocalizationManager _localization;
private readonly IJsonSerializer _jsonSerializer;
private readonly IFileSystem _fileSystem;
private readonly IChannelManager _channelManager;
private readonly LiveTvDtoService _tvDtoService;
private ILiveTvService[] _services = Array.Empty<ILiveTvService>();
private ITunerHost[] _tunerHosts = Array.Empty<ITunerHost>();
private IListingsProvider[] _listingProviders = Array.Empty<IListingsProvider>();
private readonly IFileSystem _fileSystem;
public LiveTvManager(
IServerApplicationHost appHost,
IServerConfigurationManager config,
ILoggerFactory loggerFactory,
ILogger<LiveTvManager> logger,
IItemRepository itemRepo,
IImageProcessor imageProcessor,
IUserDataManager userDataManager,
IDtoService dtoService,
IUserManager userManager,
@ -80,10 +75,11 @@ namespace Emby.Server.Implementations.LiveTv
ILocalizationManager localization,
IJsonSerializer jsonSerializer,
IFileSystem fileSystem,
Func<IChannelManager> channelManager)
IChannelManager channelManager,
LiveTvDtoService liveTvDtoService)
{
_config = config;
_logger = loggerFactory.CreateLogger(nameof(LiveTvManager));
_logger = logger;
_itemRepo = itemRepo;
_userManager = userManager;
_libraryManager = libraryManager;
@ -94,8 +90,7 @@ namespace Emby.Server.Implementations.LiveTv
_dtoService = dtoService;
_userDataManager = userDataManager;
_channelManager = channelManager;
_tvDtoService = new LiveTvDtoService(dtoService, imageProcessor, loggerFactory.CreateLogger<LiveTvDtoService>(), appHost, _libraryManager);
_tvDtoService = liveTvDtoService;
}
public event EventHandler<GenericEventArgs<TimerEventInfo>> SeriesTimerCancelled;
@ -2496,7 +2491,7 @@ namespace Emby.Server.Implementations.LiveTv
.OrderBy(i => i.SortName)
.ToList();
folders.AddRange(_channelManager().GetChannelsInternal(new MediaBrowser.Model.Channels.ChannelQuery
folders.AddRange(_channelManager.GetChannelsInternal(new MediaBrowser.Model.Channels.ChannelQuery
{
UserId = user.Id,
IsRecordingsFolder = true,

@ -23,9 +23,6 @@ namespace Emby.Server.Implementations.Localization
private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly;
private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" };
/// <summary>
/// The _configuration manager.
/// </summary>
private readonly IServerConfigurationManager _configurationManager;
private readonly IJsonSerializer _jsonSerializer;
private readonly ILogger _logger;

@ -32,22 +32,8 @@ namespace Emby.Server.Implementations.ScheduledTasks
private readonly ConcurrentQueue<Tuple<Type, TaskOptions>> _taskQueue =
new ConcurrentQueue<Tuple<Type, TaskOptions>>();
/// <summary>
/// Gets or sets the json serializer.
/// </summary>
/// <value>The json serializer.</value>
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
/// Gets or sets the application paths.
/// </summary>
/// <value>The application paths.</value>
private readonly IApplicationPaths _applicationPaths;
/// <summary>
/// Gets the logger.
/// </summary>
/// <value>The logger.</value>
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
@ -56,17 +42,17 @@ namespace Emby.Server.Implementations.ScheduledTasks
/// </summary>
/// <param name="applicationPaths">The application paths.</param>
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="logger">The logger.</param>
/// <param name="fileSystem">The filesystem manager.</param>
public TaskManager(
IApplicationPaths applicationPaths,
IJsonSerializer jsonSerializer,
ILoggerFactory loggerFactory,
ILogger<TaskManager> logger,
IFileSystem fileSystem)
{
_applicationPaths = applicationPaths;
_jsonSerializer = jsonSerializer;
_logger = loggerFactory.CreateLogger(nameof(TaskManager));
_logger = logger;
_fileSystem = fileSystem;
ScheduledTasks = Array.Empty<IScheduledTaskWorker>();

@ -15,8 +15,8 @@ namespace Emby.Server.Implementations.Security
{
public class AuthenticationRepository : BaseSqliteRepository, IAuthenticationRepository
{
public AuthenticationRepository(ILoggerFactory loggerFactory, IServerConfigurationManager config)
: base(loggerFactory.CreateLogger(nameof(AuthenticationRepository)))
public AuthenticationRepository(ILogger<AuthenticationRepository> logger, IServerConfigurationManager config)
: base(logger)
{
DbFilePath = Path.Combine(config.ApplicationPaths.DataPath, "authentication.db");
}

@ -78,12 +78,21 @@ namespace Jellyfin.Drawing.Skia
=> new HashSet<ImageFormat>() { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
/// <summary>
/// Test to determine if the native lib is available.
/// Check if the native lib is available.
/// </summary>
public static void TestSkia()
/// <returns>True if the native lib is available, otherwise false.</returns>
public static bool IsNativeLibAvailable()
{
// test an operation that requires the native library
SKPMColor.PreMultiply(SKColors.Black);
try
{
// test an operation that requires the native library
SKPMColor.PreMultiply(SKColors.Black);
return true;
}
catch (Exception)
{
return false;
}
}
private static bool IsTransparent(SKColor color)

@ -1,9 +1,13 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Emby.Drawing;
using Emby.Server.Implementations;
using Jellyfin.Drawing.Skia;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Model.IO;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Server
@ -20,27 +24,40 @@ namespace Jellyfin.Server
/// <param name="loggerFactory">The <see cref="ILoggerFactory" /> to be used by the <see cref="CoreAppHost" />.</param>
/// <param name="options">The <see cref="StartupOptions" /> to be used by the <see cref="CoreAppHost" />.</param>
/// <param name="fileSystem">The <see cref="IFileSystem" /> to be used by the <see cref="CoreAppHost" />.</param>
/// <param name="imageEncoder">The <see cref="IImageEncoder" /> to be used by the <see cref="CoreAppHost" />.</param>
/// <param name="networkManager">The <see cref="INetworkManager" /> to be used by the <see cref="CoreAppHost" />.</param>
public CoreAppHost(
ServerApplicationPaths applicationPaths,
ILoggerFactory loggerFactory,
StartupOptions options,
IFileSystem fileSystem,
IImageEncoder imageEncoder,
INetworkManager networkManager)
: base(
applicationPaths,
loggerFactory,
options,
fileSystem,
imageEncoder,
networkManager)
{
}
/// <inheritdoc />
public override bool CanSelfRestart => StartupOptions.RestartPath != null;
/// <inheritdoc/>
protected override void RegisterServices(IServiceCollection serviceCollection)
{
// Register an image encoder
bool useSkiaEncoder = SkiaEncoder.IsNativeLibAvailable();
Type imageEncoderType = useSkiaEncoder
? typeof(SkiaEncoder)
: typeof(NullImageEncoder);
serviceCollection.AddSingleton(typeof(IImageEncoder), imageEncoderType);
// Log a warning if the Skia encoder could not be used
if (!useSkiaEncoder)
{
Logger.LogWarning($"Skia not available. Will fallback to {nameof(NullImageEncoder)}.");
}
base.RegisterServices(serviceCollection);
}
/// <inheritdoc />
protected override void RestartInternal() => Program.Restart();

@ -184,7 +184,6 @@ namespace Jellyfin.Server
_loggerFactory,
options,
new ManagedFileSystem(_loggerFactory.CreateLogger<ManagedFileSystem>(), appPaths),
GetImageEncoder(appPaths),
new NetworkManager(_loggerFactory.CreateLogger<NetworkManager>()));
try
@ -204,14 +203,13 @@ namespace Jellyfin.Server
}
ServiceCollection serviceCollection = new ServiceCollection();
await appHost.InitAsync(serviceCollection, startupConfig).ConfigureAwait(false);
appHost.Init(serviceCollection);
var webHost = CreateWebHostBuilder(appHost, serviceCollection, options, startupConfig, appPaths).Build();
// Re-use the web host service provider in the app host since ASP.NET doesn't allow a custom service collection.
appHost.ServiceProvider = webHost.Services;
appHost.InitializeServices();
appHost.FindParts();
await appHost.InitializeServices().ConfigureAwait(false);
Migrations.MigrationRunner.Run(appHost, _loggerFactory);
try
@ -571,25 +569,6 @@ namespace Jellyfin.Server
}
}
private static IImageEncoder GetImageEncoder(IApplicationPaths appPaths)
{
try
{
// Test if the native lib is available
SkiaEncoder.TestSkia();
return new SkiaEncoder(
_loggerFactory.CreateLogger<SkiaEncoder>(),
appPaths);
}
catch (Exception ex)
{
_logger.LogWarning(ex, $"Skia not available. Will fallback to {nameof(NullImageEncoder)}.");
}
return new NullImageEncoder();
}
private static void StartNewInstance(StartupOptions options)
{
_logger.LogInformation("Starting new instance");

@ -332,7 +332,8 @@ namespace MediaBrowser.Api.Images
var fileInfo = _fileSystem.GetFileInfo(info.Path);
length = fileInfo.Length;
ImageDimensions size = _imageProcessor.GetImageDimensions(item, info, true);
ImageDimensions size = _imageProcessor.GetImageDimensions(item, info);
_libraryManager.UpdateImages(item);
width = size.Width;
height = size.Height;
@ -606,6 +607,12 @@ namespace MediaBrowser.Api.Images
IDictionary<string, string> headers,
bool isHeadRequest)
{
if (!image.IsLocalFile)
{
item ??= _libraryManager.GetItemById(itemId);
image = await _libraryManager.ConvertImageToLocal(item, image, request.Index ?? 0).ConfigureAwait(false);
}
var options = new ImageProcessingOptions
{
CropWhiteSpace = cropwhitespace,

@ -2,8 +2,6 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Model.Updates;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace MediaBrowser.Common
@ -119,9 +117,7 @@ namespace MediaBrowser.Common
/// Initializes this instance.
/// </summary>
/// <param name="serviceCollection">The service collection.</param>
/// <param name="startupConfig">The configuration to use for initialization.</param>
/// <returns>A task.</returns>
Task InitAsync(IServiceCollection serviceCollection, IConfiguration startupConfig);
void Init(IServiceCollection serviceCollection);
/// <summary>
/// Creates the instance.

@ -40,15 +40,6 @@ namespace MediaBrowser.Controller.Drawing
/// <returns>ImageDimensions</returns>
ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info);
/// <summary>
/// Gets the dimensions of the image.
/// </summary>
/// <param name="item">The base item.</param>
/// <param name="info">The information.</param>
/// <param name="updateItem">Whether or not the item info should be updated.</param>
/// <returns>ImageDimensions</returns>
ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info, bool updateItem);
/// <summary>
/// Gets the image cache tag.
/// </summary>

@ -459,7 +459,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions);
var outputVideoCodec = GetVideoEncoder(state, encodingOptions);
var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode;
if (!hasTextSubs)

@ -19,7 +19,6 @@ using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.System;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
@ -39,8 +38,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly IServerConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
private readonly ILocalizationManager _localization;
private readonly Func<ISubtitleEncoder> _subtitleEncoder;
private readonly IConfiguration _configuration;
private readonly Lazy<EncodingHelper> _encodingHelperFactory;
private readonly string _startupOptionFFmpegPath;
private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(2, 2);
@ -48,8 +46,6 @@ namespace MediaBrowser.MediaEncoding.Encoder
private readonly object _runningProcessesLock = new object();
private readonly List<ProcessWrapper> _runningProcesses = new List<ProcessWrapper>();
private EncodingHelper _encodingHelper;
private string _ffmpegPath;
private string _ffprobePath;
@ -58,23 +54,18 @@ namespace MediaBrowser.MediaEncoding.Encoder
IServerConfigurationManager configurationManager,
IFileSystem fileSystem,
ILocalizationManager localization,
Func<ISubtitleEncoder> subtitleEncoder,
IConfiguration configuration,
Lazy<EncodingHelper> encodingHelperFactory,
string startupOptionsFFmpegPath)
{
_logger = logger;
_configurationManager = configurationManager;
_fileSystem = fileSystem;
_localization = localization;
_encodingHelperFactory = encodingHelperFactory;
_startupOptionFFmpegPath = startupOptionsFFmpegPath;
_subtitleEncoder = subtitleEncoder;
_configuration = configuration;
}
private EncodingHelper EncodingHelper
=> LazyInitializer.EnsureInitialized(
ref _encodingHelper,
() => new EncodingHelper(this, _fileSystem, _subtitleEncoder(), _configuration));
private EncodingHelper EncodingHelper => _encodingHelperFactory.Value;
/// <inheritdoc />
public string EncoderPath => _ffmpegPath;

@ -36,60 +36,51 @@ namespace MediaBrowser.Providers.Manager
/// </summary>
public class ProviderManager : IProviderManager, IDisposable
{
/// <summary>
/// The _logger
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// The _HTTP client
/// </summary>
private readonly IHttpClient _httpClient;
/// <summary>
/// The _directory watchers
/// </summary>
private readonly ILibraryMonitor _libraryMonitor;
/// <summary>
/// Gets or sets the configuration manager.
/// </summary>
/// <value>The configuration manager.</value>
private IServerConfigurationManager ConfigurationManager { get; set; }
private readonly IFileSystem _fileSystem;
private readonly IServerApplicationPaths _appPaths;
private readonly IJsonSerializer _json;
private readonly ILibraryManager _libraryManager;
private readonly ISubtitleManager _subtitleManager;
private readonly IServerConfigurationManager _configurationManager;
private IImageProvider[] ImageProviders { get; set; }
private readonly IFileSystem _fileSystem;
private IMetadataService[] _metadataServices = { };
private IMetadataProvider[] _metadataProviders = { };
private IEnumerable<IMetadataSaver> _savers;
private readonly IServerApplicationPaths _appPaths;
private readonly IJsonSerializer _json;
private IExternalId[] _externalIds;
private readonly Func<ILibraryManager> _libraryManagerFactory;
private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();
public event EventHandler<GenericEventArgs<BaseItem>> RefreshStarted;
public event EventHandler<GenericEventArgs<BaseItem>> RefreshCompleted;
public event EventHandler<GenericEventArgs<Tuple<BaseItem, double>>> RefreshProgress;
private ISubtitleManager _subtitleManager;
/// <summary>
/// Initializes a new instance of the <see cref="ProviderManager" /> class.
/// </summary>
public ProviderManager(IHttpClient httpClient, ISubtitleManager subtitleManager, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILoggerFactory loggerFactory, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func<ILibraryManager> libraryManagerFactory, IJsonSerializer json)
public ProviderManager(
IHttpClient httpClient,
ISubtitleManager subtitleManager,
IServerConfigurationManager configurationManager,
ILibraryMonitor libraryMonitor,
ILogger<ProviderManager> logger,
IFileSystem fileSystem,
IServerApplicationPaths appPaths,
ILibraryManager libraryManager,
IJsonSerializer json)
{
_logger = loggerFactory.CreateLogger("ProviderManager");
_logger = logger;
_httpClient = httpClient;
ConfigurationManager = configurationManager;
_configurationManager = configurationManager;
_libraryMonitor = libraryMonitor;
_fileSystem = fileSystem;
_appPaths = appPaths;
_libraryManagerFactory = libraryManagerFactory;
_libraryManager = libraryManager;
_json = json;
_subtitleManager = subtitleManager;
}
@ -176,7 +167,7 @@ namespace MediaBrowser.Providers.Manager
public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken)
{
return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
}
public Task SaveImage(BaseItem item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken)
@ -188,7 +179,7 @@ namespace MediaBrowser.Providers.Manager
var fileStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, true);
return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken);
return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken);
}
public async Task<IEnumerable<RemoteImageInfo>> GetAvailableRemoteImages(BaseItem item, RemoteImageQuery query, CancellationToken cancellationToken)
@ -273,7 +264,7 @@ namespace MediaBrowser.Providers.Manager
public IEnumerable<IImageProvider> GetImageProviders(BaseItem item, ImageRefreshOptions refreshOptions)
{
return GetImageProviders(item, _libraryManagerFactory().GetLibraryOptions(item), GetMetadataOptions(item), refreshOptions, false);
return GetImageProviders(item, _libraryManager.GetLibraryOptions(item), GetMetadataOptions(item), refreshOptions, false);
}
private IEnumerable<IImageProvider> GetImageProviders(BaseItem item, LibraryOptions libraryOptions, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled)
@ -328,7 +319,7 @@ namespace MediaBrowser.Providers.Manager
private IEnumerable<IRemoteImageProvider> GetRemoteImageProviders(BaseItem item, bool includeDisabled)
{
var options = GetMetadataOptions(item);
var libraryOptions = _libraryManagerFactory().GetLibraryOptions(item);
var libraryOptions = _libraryManager.GetLibraryOptions(item);
return GetImageProviders(item, libraryOptions, options,
new ImageRefreshOptions(
@ -593,7 +584,7 @@ namespace MediaBrowser.Providers.Manager
{
var type = item.GetType().Name;
return ConfigurationManager.Configuration.MetadataOptions
return _configurationManager.Configuration.MetadataOptions
.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ??
new MetadataOptions();
}
@ -623,7 +614,7 @@ namespace MediaBrowser.Providers.Manager
/// <returns>Task.</returns>
private void SaveMetadata(BaseItem item, ItemUpdateType updateType, IEnumerable<IMetadataSaver> savers)
{
var libraryOptions = _libraryManagerFactory().GetLibraryOptions(item);
var libraryOptions = _libraryManager.GetLibraryOptions(item);
foreach (var saver in savers.Where(i => IsSaverEnabledForItem(i, item, libraryOptions, updateType, false)))
{
@ -743,7 +734,7 @@ namespace MediaBrowser.Providers.Manager
if (!searchInfo.ItemId.Equals(Guid.Empty))
{
referenceItem = _libraryManagerFactory().GetItemById(searchInfo.ItemId);
referenceItem = _libraryManager.GetItemById(searchInfo.ItemId);
}
return GetRemoteSearchResults<TItemType, TLookupType>(searchInfo, referenceItem, cancellationToken);
@ -771,7 +762,7 @@ namespace MediaBrowser.Providers.Manager
}
else
{
libraryOptions = _libraryManagerFactory().GetLibraryOptions(referenceItem);
libraryOptions = _libraryManager.GetLibraryOptions(referenceItem);
}
var options = GetMetadataOptions(referenceItem);
@ -786,11 +777,11 @@ namespace MediaBrowser.Providers.Manager
if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataLanguage))
{
searchInfo.SearchInfo.MetadataLanguage = ConfigurationManager.Configuration.PreferredMetadataLanguage;
searchInfo.SearchInfo.MetadataLanguage = _configurationManager.Configuration.PreferredMetadataLanguage;
}
if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataCountryCode))
{
searchInfo.SearchInfo.MetadataCountryCode = ConfigurationManager.Configuration.MetadataCountryCode;
searchInfo.SearchInfo.MetadataCountryCode = _configurationManager.Configuration.MetadataCountryCode;
}
var resultList = new List<RemoteSearchResult>();
@ -967,7 +958,7 @@ namespace MediaBrowser.Providers.Manager
public void OnRefreshProgress(BaseItem item, double progress)
{
var id = item.Id;
_logger.LogInformation("OnRefreshProgress {0} {1}", id.ToString("N", CultureInfo.InvariantCulture), progress);
_logger.LogDebug("OnRefreshProgress {0} {1}", id.ToString("N", CultureInfo.InvariantCulture), progress);
// TODO: Need to hunt down the conditions for this happening
_activeRefreshes.AddOrUpdate(
@ -1010,7 +1001,7 @@ namespace MediaBrowser.Providers.Manager
private async Task StartProcessingRefreshQueue()
{
var libraryManager = _libraryManagerFactory();
var libraryManager = _libraryManager;
if (_disposed)
{
@ -1088,7 +1079,7 @@ namespace MediaBrowser.Providers.Manager
private async Task RefreshArtist(MusicArtist item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
var albums = _libraryManagerFactory()
var albums = _libraryManager
.GetItemList(new InternalItemsQuery
{
IncludeItemTypes = new[] { nameof(MusicAlbum) },

@ -25,22 +25,22 @@ namespace MediaBrowser.Providers.Subtitles
{
public class SubtitleManager : ISubtitleManager
{
private ISubtitleProvider[] _subtitleProviders;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly ILibraryMonitor _monitor;
private readonly IMediaSourceManager _mediaSourceManager;
private readonly ILocalizationManager _localization;
private ILocalizationManager _localization;
private ISubtitleProvider[] _subtitleProviders;
public SubtitleManager(
ILoggerFactory loggerFactory,
ILogger<SubtitleManager> logger,
IFileSystem fileSystem,
ILibraryMonitor monitor,
IMediaSourceManager mediaSourceManager,
ILocalizationManager localizationManager)
{
_logger = loggerFactory.CreateLogger(nameof(SubtitleManager));
_logger = logger;
_fileSystem = fileSystem;
_monitor = monitor;
_mediaSourceManager = mediaSourceManager;

Loading…
Cancel
Save