Parcourir la source

Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser

Techywarrior il y a 12 ans
Parent
commit
b1cc7ccaff

+ 2 - 0
MediaBrowser.Api/Playback/Progressive/VideoService.cs

@@ -23,6 +23,7 @@ namespace MediaBrowser.Api.Playback.Progressive
     [Route("/Videos/{Id}/stream.mpeg", "GET")]
     [Route("/Videos/{Id}/stream.avi", "GET")]
     [Route("/Videos/{Id}/stream.m2ts", "GET")]
+    [Route("/Videos/{Id}/stream.3gp", "GET")]
     [Route("/Videos/{Id}/stream", "GET")]
     [Route("/Videos/{Id}/stream.ts", "HEAD")]
     [Route("/Videos/{Id}/stream.webm", "HEAD")]
@@ -34,6 +35,7 @@ namespace MediaBrowser.Api.Playback.Progressive
     [Route("/Videos/{Id}/stream.mkv", "HEAD")]
     [Route("/Videos/{Id}/stream.mpeg", "HEAD")]
     [Route("/Videos/{Id}/stream.avi", "HEAD")]
+    [Route("/Videos/{Id}/stream.3gp", "HEAD")]
     [Route("/Videos/{Id}/stream.m2ts", "HEAD")]
     [Route("/Videos/{Id}/stream", "HEAD")]
     [Api(Description = "Gets a video stream")]

+ 6 - 11
MediaBrowser.Common.Implementations/BaseApplicationHost.cs

@@ -171,6 +171,7 @@ namespace MediaBrowser.Common.Implementations
             Logger = LogManager.GetLogger("App");
 
             LogManager.ReloadLogger(ConfigurationManager.CommonConfiguration.EnableDebugLevelLogging ? LogSeverity.Debug : LogSeverity.Info);
+            OnLoggerLoaded();
 
             DiscoverTypes();
 
@@ -183,6 +184,11 @@ namespace MediaBrowser.Common.Implementations
             await RunStartupTasks().ConfigureAwait(false);
         }
 
+        protected virtual void OnLoggerLoaded()
+        {
+            
+        }
+
         /// <summary>
         /// Runs the startup tasks.
         /// </summary>
@@ -195,8 +201,6 @@ namespace MediaBrowser.Common.Implementations
 
                 Task.Run(() => ConfigureAutoRunAtStartup());
 
-                Task.Run(() => SecurityManager.LoadAllRegistrationInfo());
-
                 ConfigurationManager.ConfigurationUpdated += ConfigurationManager_ConfigurationUpdated;
             });
         }
@@ -236,11 +240,6 @@ namespace MediaBrowser.Common.Implementations
 
             var assemblies = GetComposablePartAssemblies().ToArray();
 
-            foreach (var assembly in assemblies)
-            {
-                Logger.Info("Loading {0}", assembly.FullName);
-            }
-
             AllTypes = assemblies.SelectMany(GetTypes).ToArray();
 
             AllConcreteTypes = AllTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray();
@@ -270,19 +269,15 @@ namespace MediaBrowser.Common.Implementations
                 RegisterSingleInstance(TaskManager);
 
                 HttpClient = new HttpClientManager.HttpClientManager(ApplicationPaths, Logger);
-
                 RegisterSingleInstance(HttpClient);
 
                 NetworkManager = new NetworkManager();
-
                 RegisterSingleInstance(NetworkManager);
 
                 SecurityManager = new PluginSecurityManager(this, HttpClient, JsonSerializer, ApplicationPaths);
-
                 RegisterSingleInstance(SecurityManager);
 
                 PackageManager = new PackageManager(SecurityManager, NetworkManager, HttpClient, ApplicationPaths, JsonSerializer, Logger);
-
                 RegisterSingleInstance(PackageManager);
             });
         }

+ 35 - 13
MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs

@@ -20,15 +20,15 @@ namespace MediaBrowser.Common.Implementations.Security
         /// <summary>
         /// The _is MB supporter
         /// </summary>
-        private bool? _isMBSupporter;
+        private bool? _isMbSupporter;
         /// <summary>
         /// The _is MB supporter initialized
         /// </summary>
-        private bool _isMBSupporterInitialized;
+        private bool _isMbSupporterInitialized;
         /// <summary>
         /// The _is MB supporter sync lock
         /// </summary>
-        private object _isMBSupporterSyncLock = new object();
+        private object _isMbSupporterSyncLock = new object();
 
         /// <summary>
         /// Gets a value indicating whether this instance is MB supporter.
@@ -38,14 +38,15 @@ namespace MediaBrowser.Common.Implementations.Security
         {
             get
             {
-                LazyInitializer.EnsureInitialized(ref _isMBSupporter, ref _isMBSupporterInitialized, ref _isMBSupporterSyncLock, () => GetRegistrationStatus("MBSupporter").Result.IsRegistered);
-                return _isMBSupporter.Value;
+                LazyInitializer.EnsureInitialized(ref _isMbSupporter, ref _isMbSupporterInitialized, ref _isMbSupporterSyncLock, () => GetRegistrationStatus("MBSupporter").Result.IsRegistered);
+                return _isMbSupporter.Value;
             }
         }
 
-        private IHttpClient _httpClient;
-        private IJsonSerializer _jsonSerializer;
-        private IApplicationHost _appHost;
+        private readonly IHttpClient _httpClient;
+        private readonly IJsonSerializer _jsonSerializer;
+        private readonly IApplicationHost _appHost;
+        private readonly IApplicationPaths _applciationPaths;
         private IEnumerable<IRequiresRegistration> _registeredEntities; 
         protected IEnumerable<IRequiresRegistration> RegisteredEntities
         {
@@ -65,10 +66,10 @@ namespace MediaBrowser.Common.Implementations.Security
                 throw new ArgumentNullException("httpClient");
             }
 
+            _applciationPaths = appPaths;
             _appHost = appHost;
             _httpClient = httpClient;
             _jsonSerializer = jsonSerializer;
-            MBRegistration.Init(appPaths);
         }
 
         /// <summary>
@@ -92,6 +93,9 @@ namespace MediaBrowser.Common.Implementations.Security
         /// <returns>Task{MBRegistrationRecord}.</returns>
         public async Task<MBRegistrationRecord> GetRegistrationStatus(string feature, string mb2Equivalent = null)
         {
+            // Do this on demend instead of in the constructor to delay the external assembly load
+            // Todo: Refactor external methods to take app paths as a param
+            MBRegistration.Init(_applciationPaths);
             return await MBRegistration.GetRegistrationStatus(_httpClient, _jsonSerializer, feature, mb2Equivalent).ConfigureAwait(false);
         }
 
@@ -101,9 +105,18 @@ namespace MediaBrowser.Common.Implementations.Security
         /// <value>The supporter key.</value>
         public string SupporterKey
         {
-            get { return MBRegistration.SupporterKey; }
+            get
+            {
+                // Do this on demend instead of in the constructor to delay the external assembly load
+                // Todo: Refactor external methods to take app paths as a param
+                MBRegistration.Init(_applciationPaths);
+                return MBRegistration.SupporterKey;
+            }
             set
             {
+                // Do this on demend instead of in the constructor to delay the external assembly load
+                // Todo: Refactor external methods to take app paths as a param
+                MBRegistration.Init(_applciationPaths);
                 if (value != MBRegistration.SupporterKey)
                 {
                     MBRegistration.SupporterKey = value;
@@ -119,9 +132,18 @@ namespace MediaBrowser.Common.Implementations.Security
         /// <value>The legacy key.</value>
         public string LegacyKey
         {
-            get { return MBRegistration.LegacyKey; }
+            get
+            {
+                // Do this on demend instead of in the constructor to delay the external assembly load
+                // Todo: Refactor external methods to take app paths as a param
+                MBRegistration.Init(_applciationPaths);
+                return MBRegistration.LegacyKey;
+            }
             set
             {
+                // Do this on demend instead of in the constructor to delay the external assembly load
+                // Todo: Refactor external methods to take app paths as a param
+                MBRegistration.Init(_applciationPaths);
                 if (value != MBRegistration.LegacyKey)
                 {
                     MBRegistration.LegacyKey = value;
@@ -136,8 +158,8 @@ namespace MediaBrowser.Common.Implementations.Security
         /// </summary>
         private void ResetSupporterInfo()
         {
-            _isMBSupporter = null;
-            _isMBSupporterInitialized = false;
+            _isMbSupporter = null;
+            _isMbSupporterInitialized = false;
         }
     }
 }

+ 3 - 3
MediaBrowser.Controller/Entities/BaseItem.cs

@@ -668,7 +668,7 @@ namespace MediaBrowser.Controller.Entities
             return LibraryManager.ResolvePaths<Video>(files, null).Select(video =>
             {
                 // Try to retrieve it from the db. If we don't find it, use the resolved version
-                var dbItem = Kernel.Instance.ItemRepository.RetrieveItem(video.Id) as Video;
+                var dbItem = LibraryManager.RetrieveItem(video.Id) as Video;
 
                 if (dbItem != null)
                 {
@@ -721,7 +721,7 @@ namespace MediaBrowser.Controller.Entities
             {
                 cancellationToken.ThrowIfCancellationRequested();
 
-                await Kernel.Instance.ItemRepository.SaveItem(this, cancellationToken).ConfigureAwait(false);
+                await LibraryManager.SaveItem(this, cancellationToken).ConfigureAwait(false);
             }
 
             return changed;
@@ -868,7 +868,7 @@ namespace MediaBrowser.Controller.Entities
             }
 
             //not found - load from repo
-            return Kernel.Instance.ItemRepository.RetrieveItem(id);
+            return LibraryManager.RetrieveItem(id);
         }
 
         /// <summary>

+ 3 - 3
MediaBrowser.Controller/Entities/Folder.cs

@@ -602,14 +602,14 @@ namespace MediaBrowser.Controller.Entities
                         _children.Add(item);
                     }
 
-                    saveTasks.Add(Kernel.Instance.ItemRepository.SaveItem(item, CancellationToken.None));
+                    saveTasks.Add(LibraryManager.SaveItem(item, CancellationToken.None));
                 }
 
                 await Task.WhenAll(saveTasks).ConfigureAwait(false);
 
                 //and save children in repo...
                 Logger.Debug("*** Saving " + newChildren.Count + " children for " + Name);
-                await Kernel.Instance.ItemRepository.SaveChildren(Id, newChildren, CancellationToken.None).ConfigureAwait(false);
+                await LibraryManager.SaveChildren(Id, newChildren, CancellationToken.None).ConfigureAwait(false);
             }
 
             if (changedArgs.HasChange)
@@ -726,7 +726,7 @@ namespace MediaBrowser.Controller.Entities
         /// <returns>IEnumerable{BaseItem}.</returns>
         protected virtual IEnumerable<BaseItem> GetCachedChildren()
         {
-            return Kernel.Instance.ItemRepository.RetrieveChildren(this).Select(i => i is IByReferenceItem ? LibraryManager.GetOrAddByReferenceItem(i) : i);
+            return LibraryManager.RetrieveChildren(this).Select(i => i is IByReferenceItem ? LibraryManager.GetOrAddByReferenceItem(i) : i);
         }
 
         /// <summary>

+ 1 - 1
MediaBrowser.Controller/Entities/Movies/Movie.cs

@@ -161,7 +161,7 @@ namespace MediaBrowser.Controller.Entities.Movies
             return LibraryManager.ResolvePaths<Video>(files, null).Select(video =>
             {
                 // Try to retrieve it from the db. If we don't find it, use the resolved version
-                var dbItem = Kernel.Instance.ItemRepository.RetrieveItem(video.Id) as Video;
+                var dbItem = LibraryManager.RetrieveItem(video.Id) as Video;
 
                 if (dbItem != null)
                 {

+ 0 - 77
MediaBrowser.Controller/Kernel.cs

@@ -2,13 +2,9 @@
 using MediaBrowser.Controller.Drawing;
 using MediaBrowser.Controller.Localization;
 using MediaBrowser.Controller.MediaInfo;
-using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Weather;
-using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
 
 namespace MediaBrowser.Controller
 {
@@ -76,42 +72,6 @@ namespace MediaBrowser.Controller
         /// <value>The image enhancers.</value>
         public IEnumerable<IImageEnhancer> ImageEnhancers { get; set; }
 
-        /// <summary>
-        /// Gets the list of available user repositories
-        /// </summary>
-        /// <value>The user repositories.</value>
-        public IEnumerable<IUserRepository> UserRepositories { get; set; }
-
-        /// <summary>
-        /// Gets the active user repository
-        /// </summary>
-        /// <value>The user repository.</value>
-        public IUserRepository UserRepository { get; set; }
-
-        /// <summary>
-        /// Gets the list of available item repositories
-        /// </summary>
-        /// <value>The item repositories.</value>
-        public IEnumerable<IItemRepository> ItemRepositories { get; set; }
-
-        /// <summary>
-        /// Gets the active item repository
-        /// </summary>
-        /// <value>The item repository.</value>
-        public IItemRepository ItemRepository { get; set; }
-
-        /// <summary>
-        /// Gets the list of available item repositories
-        /// </summary>
-        /// <value>The user data repositories.</value>
-        public IEnumerable<IUserDataRepository> UserDataRepositories { get; set; }
-
-        /// <summary>
-        /// Gets the active user data repository
-        /// </summary>
-        /// <value>The user data repository.</value>
-        public IUserDataRepository UserDataRepository { get; set; }
-
         private readonly IServerConfigurationManager _configurationManager;
 
         /// <summary>
@@ -124,42 +84,5 @@ namespace MediaBrowser.Controller
 
             _configurationManager = configurationManager;
         }
-
-        /// <summary>
-        /// Called when [composable parts loaded].
-        /// </summary>
-        /// <returns>Task.</returns>
-        public Task LoadRepositories(IServerConfigurationManager configurationManager)
-        {
-            // Get the current item repository
-            ItemRepository = GetRepository(ItemRepositories, configurationManager.Configuration.ItemRepository);
-            var itemRepoTask = ItemRepository.Initialize();
-
-            // Get the current user repository
-            UserRepository = GetRepository(UserRepositories, configurationManager.Configuration.UserRepository);
-            var userRepoTask = UserRepository.Initialize();
-
-            // Get the current item repository
-            UserDataRepository = GetRepository(UserDataRepositories, configurationManager.Configuration.UserDataRepository);
-            var userDataRepoTask = UserDataRepository.Initialize();
-
-            return Task.WhenAll(itemRepoTask, userRepoTask, userDataRepoTask);
-        }
-
-        /// <summary>
-        /// Gets a repository by name from a list, and returns the default if not found
-        /// </summary>
-        /// <typeparam name="T"></typeparam>
-        /// <param name="repositories">The repositories.</param>
-        /// <param name="name">The name.</param>
-        /// <returns>``0.</returns>
-        private T GetRepository<T>(IEnumerable<T> repositories, string name)
-            where T : class, IRepository
-        {
-            var enumerable = repositories as T[] ?? repositories.ToArray();
-
-            return enumerable.FirstOrDefault(r => string.Equals(r.Name, name, StringComparison.OrdinalIgnoreCase)) ??
-                   enumerable.FirstOrDefault();
-        }
     }
 }

+ 37 - 2
MediaBrowser.Controller/Library/ILibraryManager.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.IO;
+using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Sorting;
 using MediaBrowser.Model.Entities;
@@ -143,8 +144,11 @@ namespace MediaBrowser.Controller.Library
         /// <param name="resolvers">The resolvers.</param>
         /// <param name="introProviders">The intro providers.</param>
         /// <param name="itemComparers">The item comparers.</param>
-        void AddParts(IEnumerable<IResolverIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders,
-                      IEnumerable<IItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders, IEnumerable<IBaseItemComparer> itemComparers);
+        void AddParts(IEnumerable<IResolverIgnoreRule> rules, 
+            IEnumerable<IVirtualFolderCreator> pluginFolders, 
+            IEnumerable<IItemResolver> resolvers, 
+            IEnumerable<IIntroProvider> introProviders, 
+            IEnumerable<IBaseItemComparer> itemComparers);
 
         /// <summary>
         /// Sorts the specified items.
@@ -170,5 +174,36 @@ namespace MediaBrowser.Controller.Library
         /// <param name="userRootPath">The user root path.</param>
         /// <returns>UserRootFolder.</returns>
         UserRootFolder GetUserRootFolder(string userRootPath);
+
+        /// <summary>
+        /// Saves the item.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task SaveItem(BaseItem item, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Retrieves the item.
+        /// </summary>
+        /// <param name="id">The id.</param>
+        /// <returns>Task{BaseItem}.</returns>
+        BaseItem RetrieveItem(Guid id);
+
+        /// <summary>
+        /// Saves the children.
+        /// </summary>
+        /// <param name="id">The id.</param>
+        /// <param name="children">The children.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task SaveChildren(Guid id, IEnumerable<BaseItem> children, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Retrieves the children.
+        /// </summary>
+        /// <param name="parent">The parent.</param>
+        /// <returns>IEnumerable{BaseItem}.</returns>
+        IEnumerable<BaseItem> RetrieveChildren(Folder parent);
     }
 }

+ 0 - 1
MediaBrowser.Controller/MediaBrowser.Controller.csproj

@@ -58,7 +58,6 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Data" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Net" />
     <Reference Include="System.Runtime.Serialization" />

+ 7 - 14
MediaBrowser.Controller/MediaInfo/FFMpegManager.cs

@@ -1,6 +1,7 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.MediaInfo;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Providers.MediaInfo;
 using MediaBrowser.Model.Entities;
 using System;
@@ -34,31 +35,23 @@ namespace MediaBrowser.Controller.MediaInfo
         /// <value>The subtitle cache.</value>
         internal FileSystemRepository SubtitleCache { get; set; }
 
-        /// <summary>
-        /// The _logger
-        /// </summary>
-        private readonly Kernel _kernel;
-
+        private readonly ILibraryManager _libraryManager;
+        
         private readonly IServerApplicationPaths _appPaths;
         private readonly IMediaEncoder _encoder;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="FFMpegManager" /> class.
         /// </summary>
-        /// <param name="kernel">The kernel.</param>
         /// <param name="appPaths">The app paths.</param>
         /// <param name="encoder">The encoder.</param>
+        /// <param name="libraryManager">The library manager.</param>
         /// <exception cref="System.ArgumentNullException">zipClient</exception>
-        public FFMpegManager(Kernel kernel, IServerApplicationPaths appPaths, IMediaEncoder encoder)
+        public FFMpegManager(IServerApplicationPaths appPaths, IMediaEncoder encoder, ILibraryManager libraryManager)
         {
-            if (kernel == null)
-            {
-                throw new ArgumentNullException("kernel");
-            }
-
-            _kernel = kernel;
             _appPaths = appPaths;
             _encoder = encoder;
+            _libraryManager = libraryManager;
 
             VideoImageCache = new FileSystemRepository(VideoImagesDataPath);
             AudioImageCache = new FileSystemRepository(AudioImagesDataPath);
@@ -216,7 +209,7 @@ namespace MediaBrowser.Controller.MediaInfo
 
             if (saveItem && changesMade)
             {
-                await _kernel.ItemRepository.SaveItem(video, CancellationToken.None).ConfigureAwait(false);
+                await _libraryManager.SaveItem(video, CancellationToken.None).ConfigureAwait(false);
             }
         }
 

+ 22 - 1
MediaBrowser.Controller/Providers/MediaInfo/FFProbeVideoInfoProvider.cs

@@ -166,7 +166,28 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
 
             // Try to eliminate menus and intros by skipping all files at the front of the list that are less than the minimum size
             // Once we reach a file that is at least the minimum, return all subsequent ones
-            video.PlayableStreamFileNames = Directory.EnumerateFiles(root, "*.vob", SearchOption.AllDirectories).SkipWhile(f => new FileInfo(f).Length < minPlayableSize).Select(Path.GetFileName).ToList();
+            var files = Directory.EnumerateFiles(root, "*.vob", SearchOption.AllDirectories).SkipWhile(f => new FileInfo(f).Length < minPlayableSize).ToList();
+
+            // Assuming they're named "vts_05_01", take all files whose second part matches that of the first file
+            if (files.Count > 0)
+            {
+                var parts = Path.GetFileNameWithoutExtension(files[0]).Split('_');
+
+                if (parts.Length == 3)
+                {
+                    var title = parts[1];
+
+                    files = files.TakeWhile(f =>
+                    {
+                        var fileParts = Path.GetFileNameWithoutExtension(f).Split('_');
+
+                        return fileParts.Length == 3 && string.Equals(title, fileParts[1], StringComparison.OrdinalIgnoreCase);
+
+                    }).ToList();
+                }
+            }
+
+            video.PlayableStreamFileNames = files.Select(Path.GetFileName).ToList();
         }
 
         /// <summary>

+ 2 - 0
MediaBrowser.Model/DTO/StreamOptions.cs

@@ -163,6 +163,8 @@
     /// </summary>
     public enum VideoCodecs
     {
+        H263,
+
         /// <summary>
         /// The H264
         /// </summary>

+ 10 - 8
MediaBrowser.Server.Implementations/HttpServer/HttpServer.cs

@@ -49,12 +49,6 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// </summary>
         private readonly List<IRestfulService> _restServices = new List<IRestfulService>();
 
-        /// <summary>
-        /// Gets or sets the application host.
-        /// </summary>
-        /// <value>The application host.</value>
-        private IApplicationHost ApplicationHost { get; set; }
-
         /// <summary>
         /// This subscribes to HttpListener requests and finds the appropriate BaseHandler to process it
         /// </summary>
@@ -78,6 +72,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
         /// <value>The name of the server.</value>
         private string ServerName { get; set; }
 
+        private ContainerAdapter _containerAdapter;
+
         /// <summary>
         /// Initializes a new instance of the <see cref="HttpServer" /> class.
         /// </summary>
@@ -109,10 +105,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             ServerName = serverName;
             DefaultRedirectPath = defaultRedirectpath;
             _logger = logger;
-            ApplicationHost = applicationHost;
 
             EndpointHostConfig.Instance.ServiceStackHandlerFactoryPath = null;
             EndpointHostConfig.Instance.MetadataRedirectPath = "metadata";
+
+            _containerAdapter = new ContainerAdapter(applicationHost);
         }
 
         protected static readonly CultureInfo UsCulture = new CultureInfo("en-US");
@@ -135,7 +132,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
                 WriteErrorsToResponse = false
             });
 
-            container.Adapter = new ContainerAdapter(ApplicationHost);
+            container.Adapter = _containerAdapter;
 
             Plugins.Add(new SwaggerFeature());
             Plugins.Add(new CorsFeature());
@@ -214,6 +211,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
             if (Listener == null)
             {
+                _logger.Info("Creating HttpListner");
                 Listener = new HttpListener();
             }
 
@@ -221,11 +219,14 @@ namespace MediaBrowser.Server.Implementations.HttpServer
 
             UrlPrefix = urlBase;
 
+            _logger.Info("Adding HttpListener Prefixes");
             Listener.Prefixes.Add(urlBase);
 
             IsStarted = true;
+            _logger.Info("Starting HttpListner");
             Listener.Start();
 
+            _logger.Info("Creating HttpListner observable stream");
             HttpListener = CreateObservableStream().Subscribe(ProcessHttpRequestAsync);
         }
 
@@ -548,6 +549,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
             _restServices.AddRange(services);
 
             _logger.Info("Calling EndpointHost.ConfigureHost");
+
             EndpointHost.ConfigureHost(this, ServerName, CreateServiceManager());
 
             _logger.Info("Calling ServiceStack AppHost.Init");

+ 66 - 20
MediaBrowser.Server.Implementations/Library/LibraryManager.cs

@@ -7,6 +7,7 @@ using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Entities.Movies;
 using MediaBrowser.Controller.IO;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Sorting;
 using MediaBrowser.Model.Configuration;
@@ -61,6 +62,12 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <value>The comparers.</value>
         private IEnumerable<IBaseItemComparer> Comparers { get; set; }
 
+        /// <summary>
+        /// Gets the active item repository
+        /// </summary>
+        /// <value>The item repository.</value>
+        public IItemRepository ItemRepository { get; set; }
+
         #region LibraryChanged Event
         /// <summary>
         /// Fires whenever any validation routine adds or removes items.  The added and removed items are properties of the args.
@@ -95,12 +102,6 @@ namespace MediaBrowser.Server.Implementations.Library
         /// </summary>
         private readonly IUserManager _userManager;
 
-        /// <summary>
-        /// Gets or sets the kernel.
-        /// </summary>
-        /// <value>The kernel.</value>
-        private Kernel Kernel { get; set; }
-
         /// <summary>
         /// Gets or sets the configuration manager.
         /// </summary>
@@ -126,27 +127,25 @@ namespace MediaBrowser.Server.Implementations.Library
             }
         }
 
-        private ConcurrentDictionary<string, UserRootFolder> _userRootFolders =
+        private readonly ConcurrentDictionary<string, UserRootFolder> _userRootFolders =
             new ConcurrentDictionary<string, UserRootFolder>();
-        
+
         /// <summary>
         /// Initializes a new instance of the <see cref="LibraryManager" /> class.
         /// </summary>
-        /// <param name="kernel">The kernel.</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>
-        public LibraryManager(Kernel kernel, ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager)
+        public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager)
         {
-            Kernel = kernel;
             _logger = logger;
             _taskManager = taskManager;
             _userManager = userManager;
             ConfigurationManager = configurationManager;
             ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>();
 
-            ConfigurationManager.ConfigurationUpdated += kernel_ConfigurationUpdated;
+            ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated;
 
             RecordConfigurationValues(configurationManager.Configuration);
         }
@@ -159,7 +158,11 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <param name="resolvers">The resolvers.</param>
         /// <param name="introProviders">The intro providers.</param>
         /// <param name="itemComparers">The item comparers.</param>
-        public void AddParts(IEnumerable<IResolverIgnoreRule> rules, IEnumerable<IVirtualFolderCreator> pluginFolders, IEnumerable<IItemResolver> resolvers, IEnumerable<IIntroProvider> introProviders, IEnumerable<IBaseItemComparer> itemComparers)
+        public void AddParts(IEnumerable<IResolverIgnoreRule> rules,
+            IEnumerable<IVirtualFolderCreator> pluginFolders,
+            IEnumerable<IItemResolver> resolvers,
+            IEnumerable<IIntroProvider> introProviders,
+            IEnumerable<IBaseItemComparer> itemComparers)
         {
             EntityResolutionIgnoreRules = rules;
             PluginFolderCreators = pluginFolders;
@@ -212,11 +215,11 @@ namespace MediaBrowser.Server.Implementations.Library
         }
 
         /// <summary>
-        /// Handles the ConfigurationUpdated event of the kernel control.
+        /// Configurations the updated.
         /// </summary>
-        /// <param name="sender">The source of the event.</param>
-        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
-        void kernel_ConfigurationUpdated(object sender, EventArgs e)
+        /// <param name="sender">The sender.</param>
+        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
+        void ConfigurationUpdated(object sender, EventArgs e)
         {
             var config = ConfigurationManager.Configuration;
 
@@ -476,7 +479,7 @@ namespace MediaBrowser.Server.Implementations.Library
         public AggregateFolder CreateRootFolder()
         {
             var rootFolderPath = ConfigurationManager.ApplicationPaths.RootFolderPath;
-            var rootFolder = Kernel.ItemRepository.RetrieveItem(rootFolderPath.GetMBId(typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(rootFolderPath);
+            var rootFolder = RetrieveItem(rootFolderPath.GetMBId(typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(rootFolderPath);
 
             // Add in the plug-in folders
             foreach (var child in PluginFolderCreators)
@@ -494,7 +497,7 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <returns>UserRootFolder.</returns>
         public UserRootFolder GetUserRootFolder(string userRootPath)
         {
-            return _userRootFolders.GetOrAdd(userRootPath, key => Kernel.ItemRepository.RetrieveItem(userRootPath.GetMBId(typeof(UserRootFolder))) as UserRootFolder ?? (UserRootFolder)ResolvePath(userRootPath));
+            return _userRootFolders.GetOrAdd(userRootPath, key => RetrieveItem(userRootPath.GetMBId(typeof(UserRootFolder))) as UserRootFolder ?? (UserRootFolder)ResolvePath(userRootPath));
         }
         
         /// <summary>
@@ -639,7 +642,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
             var id = path.GetMBId(typeof(T));
 
-            var item = Kernel.ItemRepository.RetrieveItem(id) as T;
+            var item = RetrieveItem(id) as T;
             if (item == null)
             {
                 item = new T
@@ -899,5 +902,48 @@ namespace MediaBrowser.Server.Implementations.Library
 
             return comparer;
         }
+
+        /// <summary>
+        /// Saves the item.
+        /// </summary>
+        /// <param name="item">The item.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        public Task SaveItem(BaseItem item, CancellationToken cancellationToken)
+        {
+            return ItemRepository.SaveItem(item, cancellationToken);
+        }
+
+        /// <summary>
+        /// Retrieves the item.
+        /// </summary>
+        /// <param name="id">The id.</param>
+        /// <returns>Task{BaseItem}.</returns>
+        public BaseItem RetrieveItem(Guid id)
+        {
+            return ItemRepository.RetrieveItem(id);
+        }
+
+        /// <summary>
+        /// Saves the children.
+        /// </summary>
+        /// <param name="id">The id.</param>
+        /// <param name="children">The children.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        public Task SaveChildren(Guid id, IEnumerable<BaseItem> children, CancellationToken cancellationToken)
+        {
+            return ItemRepository.SaveChildren(id, children, cancellationToken);
+        }
+
+        /// <summary>
+        /// Retrieves the children.
+        /// </summary>
+        /// <param name="parent">The parent.</param>
+        /// <returns>IEnumerable{BaseItem}.</returns>
+        public IEnumerable<BaseItem> RetrieveChildren(Folder parent)
+        {
+            return ItemRepository.RetrieveChildren(parent);
+        }
     }
 }

+ 23 - 18
MediaBrowser.Server.Implementations/Library/UserManager.cs

@@ -4,6 +4,7 @@ using MediaBrowser.Controller;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Entities;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Connectivity;
 using MediaBrowser.Model.Logging;
 using System;
@@ -86,12 +87,6 @@ namespace MediaBrowser.Server.Implementations.Library
         /// </summary>
         private readonly ILogger _logger;
 
-        /// <summary>
-        /// Gets or sets the kernel.
-        /// </summary>
-        /// <value>The kernel.</value>
-        private Kernel Kernel { get; set; }
-
         /// <summary>
         /// Gets or sets the configuration manager.
         /// </summary>
@@ -99,17 +94,27 @@ namespace MediaBrowser.Server.Implementations.Library
         private IServerConfigurationManager ConfigurationManager { get; set; }
 
         private readonly ConcurrentDictionary<string, Task<UserItemData>> _userData = new ConcurrentDictionary<string, Task<UserItemData>>();
-        
+
+        /// <summary>
+        /// Gets the active user data repository
+        /// </summary>
+        /// <value>The user data repository.</value>
+        public IUserDataRepository UserDataRepository { get; set; }
+
+        /// <summary>
+        /// Gets the active user repository
+        /// </summary>
+        /// <value>The user repository.</value>
+        public IUserRepository UserRepository { get; set; }
+
         /// <summary>
         /// Initializes a new instance of the <see cref="UserManager" /> class.
         /// </summary>
-        /// <param name="kernel">The kernel.</param>
         /// <param name="logger">The logger.</param>
         /// <param name="configurationManager">The configuration manager.</param>
-        public UserManager(Kernel kernel, ILogger logger, IServerConfigurationManager configurationManager)
+        public UserManager(ILogger logger, IServerConfigurationManager configurationManager)
         {
             _logger = logger;
-            Kernel = kernel;
             ConfigurationManager = configurationManager;
         }
 
@@ -250,7 +255,7 @@ namespace MediaBrowser.Server.Implementations.Library
             }
 
             // Save this directly. No need to fire off all the events for this.
-            return Kernel.UserRepository.SaveUser(user, CancellationToken.None);
+            return UserRepository.SaveUser(user, CancellationToken.None);
         }
 
         /// <summary>
@@ -334,7 +339,7 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <returns>IEnumerable{User}.</returns>
         private IEnumerable<User> LoadUsers()
         {
-            var users = Kernel.UserRepository.RetrieveAllUsers().ToList();
+            var users = UserRepository.RetrieveAllUsers().ToList();
 
             // There always has to be at least one user.
             if (users.Count == 0)
@@ -343,7 +348,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
                 var user = InstantiateNewUser(name);
 
-                var task = Kernel.UserRepository.SaveUser(user, CancellationToken.None);
+                var task = UserRepository.SaveUser(user, CancellationToken.None);
 
                 // Hate having to block threads
                 Task.WaitAll(task);
@@ -422,7 +427,7 @@ namespace MediaBrowser.Server.Implementations.Library
 
             user.DateModified = DateTime.UtcNow;
 
-            await Kernel.UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
+            await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
 
             OnUserUpdated(user);
         }
@@ -452,7 +457,7 @@ namespace MediaBrowser.Server.Implementations.Library
             list.Add(user);
             Users = list;
 
-            await Kernel.UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
+            await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
 
             return user;
         }
@@ -481,7 +486,7 @@ namespace MediaBrowser.Server.Implementations.Library
                 throw new ArgumentException(string.Format("The user '{0}' be deleted because there must be at least one user in the system.", user.Name));
             }
 
-            await Kernel.UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
+            await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
 
             OnUserDeleted(user);
 
@@ -713,7 +718,7 @@ namespace MediaBrowser.Server.Implementations.Library
             var key = userId + userDataId.ToString();
             try
             {
-                await Kernel.Instance.UserDataRepository.SaveUserData(userId, userDataId, userData, cancellationToken).ConfigureAwait(false);
+                await UserDataRepository.SaveUserData(userId, userDataId, userData, cancellationToken).ConfigureAwait(false);
 
                 var newValue = Task.FromResult(userData);
 
@@ -749,7 +754,7 @@ namespace MediaBrowser.Server.Implementations.Library
         /// <returns>Task{UserItemData}.</returns>
         private async Task<UserItemData> RetrieveUserData(Guid userId, Guid userDataId)
         {
-            var userdata = await Kernel.Instance.UserDataRepository.GetUserData(userId, userDataId).ConfigureAwait(false);
+            var userdata = await UserDataRepository.GetUserData(userId, userDataId).ConfigureAwait(false);
 
             return userdata ?? new UserItemData();
         }

+ 0 - 2
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -109,8 +109,6 @@
       <HintPath>..\packages\Rx-Linq.2.1.30214.0\lib\Net45\System.Reactive.Linq.dll</HintPath>
     </Reference>
     <Reference Include="System.Web" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />

+ 103 - 42
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -146,8 +146,12 @@ namespace MediaBrowser.ServerApplication
         /// <value>The display preferences manager.</value>
         internal IDisplayPreferencesManager DisplayPreferencesManager { get; set; }
 
+        /// <summary>
+        /// Gets or sets the media encoder.
+        /// </summary>
+        /// <value>The media encoder.</value>
         private IMediaEncoder MediaEncoder { get; set; }
-        
+
         /// <summary>
         /// The full path to our startmenu shortcut
         /// </summary>
@@ -156,22 +160,33 @@ namespace MediaBrowser.ServerApplication
             get { return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Media Browser 3", "Media Browser Server.lnk"); }
         }
 
+        private Task<IHttpServer> _httpServerCreationTask;
+
         /// <summary>
         /// Runs the startup tasks.
         /// </summary>
         /// <returns>Task.</returns>
         protected override async Task RunStartupTasks()
         {
-            // Do these before allowing the base method to run, which will invoke startup scheduled tasks
-            await ServerKernel.LoadRepositories(ServerConfigurationManager).ConfigureAwait(false);
-
             await base.RunStartupTasks().ConfigureAwait(false);
 
             DirectoryWatchers.Start();
 
+            Logger.Info("Core startup complete");
+
             Parallel.ForEach(GetExports<IServerEntryPoint>(), entryPoint => entryPoint.Run());
         }
 
+        /// <summary>
+        /// Called when [logger loaded].
+        /// </summary>
+        protected override void OnLoggerLoaded()
+        {
+            base.OnLoggerLoaded();
+
+            _httpServerCreationTask = Task.Run(() => ServerFactory.CreateServer(this, Logger, "Media Browser", "index.html"));
+        }
+
         /// <summary>
         /// Registers resources that classes will depend on
         /// </summary>
@@ -192,22 +207,16 @@ namespace MediaBrowser.ServerApplication
 
             RegisterSingleInstance<IWebSocketServer>(() => new AlchemyServer(Logger));
 
-            RegisterSingleInstance<IIsoManager>(new PismoIsoManager(Logger));
-            RegisterSingleInstance<IBlurayExaminer>(new BdInfoExaminer());
+            RegisterSingleInstance<IIsoManager>(() => new PismoIsoManager(Logger));
+            RegisterSingleInstance<IBlurayExaminer>(() => new BdInfoExaminer());
 
             ZipClient = new DotNetZipClient();
             RegisterSingleInstance(ZipClient);
 
-            HttpServer = ServerFactory.CreateServer(this, Logger, "Media Browser", "index.html");
-            RegisterSingleInstance(HttpServer, false);
-
-            ServerManager = new ServerManager(this, JsonSerializer, Logger, ServerConfigurationManager, ServerKernel);
-            RegisterSingleInstance(ServerManager);
-
-            UserManager = new UserManager(ServerKernel, Logger, ServerConfigurationManager);
+            UserManager = new UserManager(Logger, ServerConfigurationManager);
             RegisterSingleInstance(UserManager);
 
-            LibraryManager = new LibraryManager(ServerKernel, Logger, TaskManager, UserManager, ServerConfigurationManager);
+            LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager);
             RegisterSingleInstance(LibraryManager);
 
             InstallationManager = new InstallationManager(HttpClient, PackageManager, JsonSerializer, Logger, this);
@@ -227,9 +236,20 @@ namespace MediaBrowser.ServerApplication
             MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), ZipClient, ApplicationPaths, JsonSerializer);
             RegisterSingleInstance(MediaEncoder);
 
-            await ConfigureRepositories().ConfigureAwait(false);
+            HttpServer = await _httpServerCreationTask.ConfigureAwait(false);
+            RegisterSingleInstance(HttpServer, false);
+
+            ServerManager = new ServerManager(this, JsonSerializer, Logger, ServerConfigurationManager, ServerKernel);
+            RegisterSingleInstance(ServerManager);
+
+            var displayPreferencesTask = Task.Run(async () => await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false));
+            var itemsTask = Task.Run(async () => await ConfigureItemRepositories().ConfigureAwait(false));
+            var userdataTask = Task.Run(async () => await ConfigureUserDataRepositories().ConfigureAwait(false));
+            var userTask = Task.Run(async () => await ConfigureUserRepositories().ConfigureAwait(false));
+
+            await Task.WhenAll(itemsTask, userTask, displayPreferencesTask, userdataTask).ConfigureAwait(false);
+
             SetKernelProperties();
-            SetStaticProperties();
         }
 
         /// <summary>
@@ -237,16 +257,13 @@ namespace MediaBrowser.ServerApplication
         /// </summary>
         private void SetKernelProperties()
         {
-            ServerKernel.FFMpegManager = new FFMpegManager(ServerKernel, ApplicationPaths, MediaEncoder);
-            ServerKernel.ImageManager = new ImageManager(ServerKernel, LogManager.GetLogger("ImageManager"), ApplicationPaths);
-
             Parallel.Invoke(
-                () => ServerKernel.UserDataRepositories = GetExports<IUserDataRepository>(),
-                () => ServerKernel.UserRepositories = GetExports<IUserRepository>(),
-                () => ServerKernel.ItemRepositories = GetExports<IItemRepository>(),
+                () => ServerKernel.FFMpegManager = new FFMpegManager(ApplicationPaths, MediaEncoder, LibraryManager),
+                () => ServerKernel.ImageManager = new ImageManager(ServerKernel, LogManager.GetLogger("ImageManager"), ApplicationPaths),
                 () => ServerKernel.WeatherProviders = GetExports<IWeatherProvider>(),
                 () => ServerKernel.ImageEnhancers = GetExports<IImageEnhancer>().OrderBy(e => e.Priority).ToArray(),
-                () => ServerKernel.StringFiles = GetExports<LocalizedStringData>()
+                () => ServerKernel.StringFiles = GetExports<LocalizedStringData>(),
+                SetStaticProperties
                 );
         }
 
@@ -254,15 +271,56 @@ namespace MediaBrowser.ServerApplication
         /// Configures the repositories.
         /// </summary>
         /// <returns>Task.</returns>
-        private async Task ConfigureRepositories()
+        private async Task ConfigureDisplayPreferencesRepositories()
         {
-            var displayPreferencesRepositories = GetExports<IDisplayPreferencesRepository>();
+            var repositories = GetExports<IDisplayPreferencesRepository>();
 
-            var repo = GetRepository(displayPreferencesRepositories, ServerConfigurationManager.Configuration.DisplayPreferencesRepository);
+            var repository = GetRepository(repositories, ServerConfigurationManager.Configuration.DisplayPreferencesRepository);
 
-            await repo.Initialize().ConfigureAwait(false);
+            await repository.Initialize().ConfigureAwait(false);
 
-            ((DisplayPreferencesManager)DisplayPreferencesManager).Repository = repo;
+            ((DisplayPreferencesManager)DisplayPreferencesManager).Repository = repository;
+        }
+
+        /// <summary>
+        /// Configures the item repositories.
+        /// </summary>
+        /// <returns>Task.</returns>
+        private async Task ConfigureItemRepositories()
+        {
+            var repositories = GetExports<IItemRepository>();
+
+            var repository = GetRepository(repositories, ServerConfigurationManager.Configuration.ItemRepository);
+
+            await repository.Initialize().ConfigureAwait(false);
+
+            ((LibraryManager)LibraryManager).ItemRepository = repository;
+        }
+
+        /// <summary>
+        /// Configures the user data repositories.
+        /// </summary>
+        /// <returns>Task.</returns>
+        private async Task ConfigureUserDataRepositories()
+        {
+            var repositories = GetExports<IUserDataRepository>();
+
+            var repository = GetRepository(repositories, ServerConfigurationManager.Configuration.UserDataRepository);
+
+            await repository.Initialize().ConfigureAwait(false);
+
+            ((UserManager)UserManager).UserDataRepository = repository;
+        }
+
+        private async Task ConfigureUserRepositories()
+        {
+            var repositories = GetExports<IUserRepository>();
+
+            var repository = GetRepository(repositories, ServerConfigurationManager.Configuration.UserRepository);
+
+            await repository.Initialize().ConfigureAwait(false);
+
+            ((UserManager)UserManager).UserRepository = repository;
         }
 
         /// <summary>
@@ -286,8 +344,6 @@ namespace MediaBrowser.ServerApplication
         /// </summary>
         protected override void FindParts()
         {
-            base.FindParts();
-
             if (IsFirstRun)
             {
                 RegisterServerWithAdministratorAccess();
@@ -295,6 +351,8 @@ namespace MediaBrowser.ServerApplication
 
             Parallel.Invoke(
 
+                () => base.FindParts(),
+
                 () =>
                 {
                     HttpServer.Init(GetExports<IRestfulService>(false));
@@ -305,19 +363,22 @@ namespace MediaBrowser.ServerApplication
 
                 () => LibraryManager.AddParts(GetExports<IResolverIgnoreRule>(), GetExports<IVirtualFolderCreator>(), GetExports<IItemResolver>(), GetExports<IIntroProvider>(), GetExports<IBaseItemComparer>()),
 
-                () => ProviderManager.AddMetadataProviders(GetExports<BaseMetadataProvider>().ToArray())
-                );
-
-            UdpServer = new UdpServer(Logger, NetworkManager, ServerConfigurationManager);
+                () => ProviderManager.AddMetadataProviders(GetExports<BaseMetadataProvider>().ToArray()),
 
-            try
-            {
-                UdpServer.Start(UdpServerPort);
-            }
-            catch (SocketException ex)
-            {
-                Logger.ErrorException("Failed to start UDP Server", ex);
-            }
+                () =>
+                {
+                    UdpServer = new UdpServer(Logger, NetworkManager, ServerConfigurationManager);
+
+                    try
+                    {
+                        UdpServer.Start(UdpServerPort);
+                    }
+                    catch (SocketException ex)
+                    {
+                        Logger.ErrorException("Failed to start UDP Server", ex);
+                    }
+                }
+                );
         }
 
         /// <summary>

+ 57 - 0
MediaBrowser.ServerApplication/EntryPoints/LoadRegistrations.cs

@@ -0,0 +1,57 @@
+using MediaBrowser.Common.Security;
+using MediaBrowser.Controller.Plugins;
+using MediaBrowser.Model.Logging;
+using System;
+
+namespace MediaBrowser.ServerApplication.EntryPoints
+{
+    /// <summary>
+    /// Class LoadRegistrations
+    /// </summary>
+    public class LoadRegistrations : IServerEntryPoint
+    {
+        /// <summary>
+        /// The _security manager
+        /// </summary>
+        private readonly ISecurityManager _securityManager;
+
+        /// <summary>
+        /// The _logger
+        /// </summary>
+        private readonly ILogger _logger;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="LoadRegistrations" /> class.
+        /// </summary>
+        /// <param name="securityManager">The security manager.</param>
+        /// <param name="logManager">The log manager.</param>
+        public LoadRegistrations(ISecurityManager securityManager, ILogManager logManager)
+        {
+            _securityManager = securityManager;
+
+            _logger = logManager.GetLogger("Registration Loader");
+        }
+
+        /// <summary>
+        /// Runs this instance.
+        /// </summary>
+        public async void Run()
+        {
+            try
+            {
+                await _securityManager.LoadAllRegistrationInfo().ConfigureAwait(false);
+            }
+            catch (Exception ex)
+            {
+                _logger.ErrorException("Error loading registration info", ex);
+            }
+        }
+
+        /// <summary>
+        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
+        /// </summary>
+        public void Dispose()
+        {
+        }
+    }
+}

+ 1 - 0
MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj

@@ -181,6 +181,7 @@
     <Reference Include="PresentationFramework" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="EntryPoints\LoadRegistrations.cs" />
     <Compile Include="EntryPoints\NewItemNotifier.cs" />
     <Compile Include="EntryPoints\RefreshUsersMetadata.cs" />
     <Compile Include="EntryPoints\StartupWizard.cs" />