using MediaBrowser.Api; using MediaBrowser.Common.Implementations; using MediaBrowser.Common.Implementations.HttpServer; using MediaBrowser.Common.Implementations.Logging; using MediaBrowser.Common.Implementations.NetworkManagement; using MediaBrowser.Common.Implementations.ScheduledTasks; using MediaBrowser.Common.Implementations.Serialization; using MediaBrowser.Common.Implementations.ServerManager; using MediaBrowser.Common.IO; using MediaBrowser.Common.Kernel; using MediaBrowser.Common.Net; using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Common.Updates; using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; using MediaBrowser.Controller.Updates; using MediaBrowser.IsoMounter; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; using MediaBrowser.Model.Updates; using MediaBrowser.Server.Implementations; using MediaBrowser.Server.Implementations.BdInfo; using MediaBrowser.Server.Implementations.Library; using MediaBrowser.ServerApplication.Implementations; using MediaBrowser.WebDashboard.Api; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.ServerApplication { /// /// Class CompositionRoot /// public class ApplicationHost : BaseApplicationHost, IApplicationHost { /// /// Gets or sets the kernel. /// /// The kernel. internal Kernel Kernel { get; private set; } /// /// The json serializer /// private readonly IJsonSerializer _jsonSerializer = new JsonSerializer(); /// /// The _XML serializer /// private readonly IXmlSerializer _xmlSerializer = new XmlSerializer(); private WebSocketEvents _webSocketEvents; /// /// Gets the server application paths. /// /// The server application paths. protected IServerApplicationPaths ServerApplicationPaths { get { return (IServerApplicationPaths)ApplicationPaths; } } /// /// Initializes a new instance of the class. /// /// The logger. public ApplicationHost() : base() { Kernel = new Kernel(this, ServerApplicationPaths, _xmlSerializer, Logger); var networkManager = new NetworkManager(); var serverManager = new ServerManager(this, Kernel, networkManager, _jsonSerializer, Logger); var taskManager = new TaskManager(ApplicationPaths, _jsonSerializer, Logger, serverManager); LogManager.ReloadLogger(Kernel.Configuration.EnableDebugLevelLogging ? LogSeverity.Debug : LogSeverity.Info); Logger.Info("Version {0} initializing", ApplicationVersion); RegisterResources(taskManager, networkManager, serverManager); FindParts(); } /// /// Gets the application paths. /// /// IApplicationPaths. protected override IApplicationPaths GetApplicationPaths() { return new ServerApplicationPaths(); } /// /// Gets the log manager. /// /// ILogManager. protected override ILogManager GetLogManager() { return new NlogManager(ApplicationPaths.LogDirectoryPath, "Server"); } /// /// Registers resources that classes will depend on /// protected override void RegisterResources(ITaskManager taskManager, INetworkManager networkManager, IServerManager serverManager) { base.RegisterResources(taskManager, networkManager, serverManager); RegisterSingleInstance(Kernel); RegisterSingleInstance(Kernel); RegisterSingleInstance(this); RegisterSingleInstance(ServerApplicationPaths); RegisterSingleInstance(new PismoIsoManager(Logger)); RegisterSingleInstance(new BdInfoExaminer()); RegisterSingleInstance(new DotNetZipClient()); RegisterSingleInstance(_jsonSerializer); RegisterSingleInstance(_xmlSerializer); RegisterSingleInstance(ServerFactory.CreateServer(this, ProtobufSerializer, Logger, "Media Browser", "index.html"), false); var userManager = new UserManager(Kernel, Logger); RegisterSingleInstance(userManager); RegisterSingleInstance(new LibraryManager(Kernel, Logger, taskManager, userManager)); } /// /// Finds the parts. /// protected override void FindParts() { base.FindParts(); Resolve().AddParts(GetExports(), GetExports(), GetExports()); Kernel.InstallationManager = (InstallationManager)CreateInstance(typeof(InstallationManager)); _webSocketEvents = new WebSocketEvents(Resolve(), Resolve(), Resolve(), Resolve(), Resolve(), Kernel.InstallationManager); } /// /// Restarts this instance. /// public void Restart() { App.Instance.Restart(); } /// /// Gets or sets a value indicating whether this instance can self update. /// /// true if this instance can self update; otherwise, false. public bool CanSelfUpdate { get { return Kernel.Configuration.EnableAutoUpdate; } } /// /// Checks for update. /// /// The cancellation token. /// The progress. /// Task{CheckForUpdateResult}. public async Task CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress progress) { var pkgManager = Resolve(); var availablePackages = await pkgManager.GetAvailablePackages(Resolve(), Resolve(), Kernel.SecurityManager, Kernel.ResourcePools, Resolve(), CancellationToken.None).ConfigureAwait(false); var version = Kernel.InstallationManager.GetLatestCompatibleVersion(availablePackages, "MBServer", Kernel.Configuration.SystemUpdateLevel); return version != null ? new CheckForUpdateResult { AvailableVersion = version.version, IsUpdateAvailable = version.version > ApplicationVersion, Package = version } : new CheckForUpdateResult { AvailableVersion = ApplicationVersion, IsUpdateAvailable = false }; } /// /// Updates the application. /// /// The package that contains the update /// The cancellation token. /// The progress. /// Task. public Task UpdateApplication(PackageVersionInfo package, CancellationToken cancellationToken, IProgress progress) { var pkgManager = Resolve(); return pkgManager.InstallPackage(Resolve(), Resolve(), Kernel.ResourcePools, progress, Kernel.ApplicationPaths, package, cancellationToken); } /// /// Gets the composable part assemblies. /// /// IEnumerable{Assembly}. protected override IEnumerable GetComposablePartAssemblies() { // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that // This will prevent the .dll file from getting locked, and allow us to replace it when needed foreach (var pluginAssembly in Directory .EnumerateFiles(ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) .Select(LoadAssembly).Where(a => a != null)) { yield return pluginAssembly; } // Include composable parts in the Api assembly yield return typeof(ApiService).Assembly; // Include composable parts in the Dashboard assembly yield return typeof(DashboardInfo).Assembly; // Include composable parts in the Model assembly yield return typeof(SystemInfo).Assembly; // Include composable parts in the Common assembly yield return typeof(IKernel).Assembly; // Include composable parts in the Controller assembly yield return typeof(Kernel).Assembly; // Common implementations yield return typeof(TaskManager).Assembly; // Server implementations yield return typeof(ServerApplicationPaths).Assembly; // Include composable parts in the running assembly yield return GetType().Assembly; } /// /// Shuts down. /// public void Shutdown() { App.Instance.Dispatcher.Invoke(App.Instance.Shutdown); } /// /// Releases unmanaged and - optionally - managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool dispose) { if (dispose) { if (_webSocketEvents != null) { _webSocketEvents.Dispose(); } } base.Dispose(dispose); } } }