ApplicationHost.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. using BDInfo;
  2. using MediaBrowser.ClickOnce;
  3. using MediaBrowser.Common.Implementations;
  4. using MediaBrowser.Common.Implementations.ScheduledTasks;
  5. using MediaBrowser.Common.Implementations.Serialization;
  6. using MediaBrowser.Common.IO;
  7. using MediaBrowser.Common.Kernel;
  8. using MediaBrowser.Common.Net;
  9. using MediaBrowser.Common.ScheduledTasks;
  10. using MediaBrowser.Controller;
  11. using MediaBrowser.IsoMounter;
  12. using MediaBrowser.Logging.Nlog;
  13. using MediaBrowser.Model.IO;
  14. using MediaBrowser.Model.MediaInfo;
  15. using MediaBrowser.Model.Serialization;
  16. using MediaBrowser.Model.System;
  17. using MediaBrowser.Model.Updates;
  18. using MediaBrowser.Networking.HttpManager;
  19. using MediaBrowser.Networking.HttpServer;
  20. using MediaBrowser.Networking.Management;
  21. using MediaBrowser.Networking.Udp;
  22. using MediaBrowser.Networking.WebSocket;
  23. using MediaBrowser.Server.Implementations;
  24. using MediaBrowser.ServerApplication.Implementations;
  25. using System;
  26. using System.Collections.Generic;
  27. using System.Diagnostics;
  28. using System.IO;
  29. using System.Linq;
  30. using System.Reflection;
  31. using System.Threading;
  32. using System.Threading.Tasks;
  33. namespace MediaBrowser.ServerApplication
  34. {
  35. /// <summary>
  36. /// Class CompositionRoot
  37. /// </summary>
  38. public class ApplicationHost : BaseApplicationHost, IApplicationHost
  39. {
  40. /// <summary>
  41. /// Gets or sets the log file path.
  42. /// </summary>
  43. /// <value>The log file path.</value>
  44. public string LogFilePath { get; private set; }
  45. /// <summary>
  46. /// Gets or sets the kernel.
  47. /// </summary>
  48. /// <value>The kernel.</value>
  49. internal Kernel Kernel { get; private set; }
  50. /// <summary>
  51. /// The json serializer
  52. /// </summary>
  53. private readonly IJsonSerializer _jsonSerializer = new JsonSerializer();
  54. /// <summary>
  55. /// The _XML serializer
  56. /// </summary>
  57. private readonly IXmlSerializer _xmlSerializer = new XmlSerializer();
  58. /// <summary>
  59. /// The _application paths
  60. /// </summary>
  61. private readonly IServerApplicationPaths _applicationPaths = new ServerApplicationPaths();
  62. /// <summary>
  63. /// The _task manager
  64. /// </summary>
  65. private readonly ITaskManager _taskManager;
  66. /// <summary>
  67. /// The _task manager
  68. /// </summary>
  69. private readonly IHttpServer _httpServer;
  70. /// <summary>
  71. /// Gets a value indicating whether this instance is first run.
  72. /// </summary>
  73. /// <value><c>true</c> if this instance is first run; otherwise, <c>false</c>.</value>
  74. public bool IsFirstRun { get; private set; }
  75. /// <summary>
  76. /// Initializes a new instance of the <see cref="ApplicationHost" /> class.
  77. /// </summary>
  78. /// <param name="logger">The logger.</param>
  79. public ApplicationHost()
  80. : base()
  81. {
  82. IsFirstRun = !File.Exists(_applicationPaths.SystemConfigurationFilePath);
  83. Logger = new NLogger("App");
  84. DiscoverTypes();
  85. _taskManager = new TaskManager(_applicationPaths, _jsonSerializer, Logger);
  86. Kernel = new Kernel(this, _applicationPaths, _xmlSerializer, _taskManager, Logger);
  87. ReloadLogger();
  88. Logger.Info("Version {0} initializing", ApplicationVersion);
  89. _httpServer = ServerFactory.CreateServer(this, ProtobufSerializer, Logger, "Media Browser", "index.html");
  90. RegisterResources();
  91. FindParts();
  92. }
  93. /// <summary>
  94. /// Registers resources that classes will depend on
  95. /// </summary>
  96. private void RegisterResources()
  97. {
  98. RegisterSingleInstance<IKernel>(Kernel);
  99. RegisterSingleInstance(Kernel);
  100. RegisterSingleInstance<IApplicationHost>(this);
  101. RegisterSingleInstance(Logger);
  102. RegisterSingleInstance(_applicationPaths);
  103. RegisterSingleInstance<IApplicationPaths>(_applicationPaths);
  104. RegisterSingleInstance(_taskManager);
  105. RegisterSingleInstance<IIsoManager>(new PismoIsoManager(Logger));
  106. RegisterSingleInstance<IBlurayExaminer>(new BdInfoExaminer());
  107. RegisterSingleInstance<IHttpClient>(new HttpManager(_applicationPaths, Logger));
  108. RegisterSingleInstance<INetworkManager>(new NetworkManager());
  109. RegisterSingleInstance<IZipClient>(new DotNetZipClient());
  110. RegisterSingleInstance<IWebSocketServer>(() => new AlchemyServer(Logger));
  111. RegisterSingleInstance(_jsonSerializer);
  112. RegisterSingleInstance(_xmlSerializer);
  113. RegisterSingleInstance(ProtobufSerializer);
  114. RegisterSingleInstance<IUdpServer>(new UdpServer());
  115. RegisterSingleInstance(_httpServer);
  116. }
  117. /// <summary>
  118. /// Finds the parts.
  119. /// </summary>
  120. private void FindParts()
  121. {
  122. _taskManager.AddTasks(GetExports<IScheduledTask>(false));
  123. _httpServer.Init(GetExports<IRestfulService>(false));
  124. }
  125. /// <summary>
  126. /// Restarts this instance.
  127. /// </summary>
  128. /// <exception cref="System.NotImplementedException"></exception>
  129. public void Restart()
  130. {
  131. App.Instance.Restart();
  132. }
  133. /// <summary>
  134. /// Reloads the logger.
  135. /// </summary>
  136. /// <exception cref="System.NotImplementedException"></exception>
  137. public void ReloadLogger()
  138. {
  139. LogFilePath = Path.Combine(_applicationPaths.LogDirectoryPath, "Server-" + DateTime.Now.Ticks + ".log");
  140. NlogManager.AddFileTarget(LogFilePath, Kernel.Configuration.EnableDebugLevelLogging);
  141. }
  142. /// <summary>
  143. /// Gets or sets a value indicating whether this instance can self update.
  144. /// </summary>
  145. /// <value><c>true</c> if this instance can self update; otherwise, <c>false</c>.</value>
  146. public bool CanSelfUpdate
  147. {
  148. get { return ClickOnceHelper.IsNetworkDeployed; }
  149. }
  150. /// <summary>
  151. /// Checks for update.
  152. /// </summary>
  153. /// <param name="cancellationToken">The cancellation token.</param>
  154. /// <param name="progress">The progress.</param>
  155. /// <returns>Task{CheckForUpdateResult}.</returns>
  156. public Task<CheckForUpdateResult> CheckForApplicationUpdate(CancellationToken cancellationToken, IProgress<double> progress)
  157. {
  158. return new ApplicationUpdateCheck().CheckForApplicationUpdate(cancellationToken, progress);
  159. }
  160. /// <summary>
  161. /// Updates the application.
  162. /// </summary>
  163. /// <param name="cancellationToken">The cancellation token.</param>
  164. /// <param name="progress">The progress.</param>
  165. /// <returns>Task.</returns>
  166. public Task UpdateApplication(CancellationToken cancellationToken, IProgress<double> progress)
  167. {
  168. return new ApplicationUpdater().UpdateApplication(cancellationToken, progress);
  169. }
  170. /// <summary>
  171. /// Gets the composable part assemblies.
  172. /// </summary>
  173. /// <returns>IEnumerable{Assembly}.</returns>
  174. protected override IEnumerable<Assembly> GetComposablePartAssemblies()
  175. {
  176. // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that
  177. // This will prevent the .dll file from getting locked, and allow us to replace it when needed
  178. foreach (var pluginAssembly in Directory
  179. .EnumerateFiles(_applicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly)
  180. .Select(LoadAssembly).Where(a => a != null))
  181. {
  182. yield return pluginAssembly;
  183. }
  184. var runningDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
  185. var corePluginDirectory = Path.Combine(runningDirectory, "CorePlugins");
  186. // This will prevent the .dll file from getting locked, and allow us to replace it when needed
  187. foreach (var pluginAssembly in Directory
  188. .EnumerateFiles(corePluginDirectory, "*.dll", SearchOption.TopDirectoryOnly)
  189. .Select(LoadAssembly).Where(a => a != null))
  190. {
  191. yield return pluginAssembly;
  192. }
  193. // Include composable parts in the Model assembly
  194. yield return typeof(SystemInfo).Assembly;
  195. // Include composable parts in the Common assembly
  196. yield return typeof(IKernel).Assembly;
  197. // Include composable parts in the Controller assembly
  198. yield return typeof(Kernel).Assembly;
  199. // Common implementations
  200. yield return typeof(TaskManager).Assembly;
  201. // Server implementations
  202. yield return typeof(ServerApplicationPaths).Assembly;
  203. // Include composable parts in the running assembly
  204. yield return GetType().Assembly;
  205. }
  206. }
  207. }