Răsfoiți Sursa

#680 - Support new episode file sorting added dummy results repository

Luke Pulverenti 11 ani în urmă
părinte
comite
d4bdd42acf

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

@@ -139,6 +139,7 @@
     <Compile Include="News\INewsService.cs" />
     <Compile Include="News\INewsService.cs" />
     <Compile Include="Notifications\INotificationsRepository.cs" />
     <Compile Include="Notifications\INotificationsRepository.cs" />
     <Compile Include="Notifications\NotificationUpdateEventArgs.cs" />
     <Compile Include="Notifications\NotificationUpdateEventArgs.cs" />
+    <Compile Include="Persistence\IFileSortingRepository.cs" />
     <Compile Include="Persistence\MediaStreamQuery.cs" />
     <Compile Include="Persistence\MediaStreamQuery.cs" />
     <Compile Include="Providers\IDynamicInfoProvider.cs" />
     <Compile Include="Providers\IDynamicInfoProvider.cs" />
     <Compile Include="Providers\IImageProvider.cs" />
     <Compile Include="Providers\IImageProvider.cs" />

+ 25 - 0
MediaBrowser.Controller/Persistence/IFileSortingRepository.cs

@@ -0,0 +1,25 @@
+using MediaBrowser.Model.FileSorting;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Controller.Persistence
+{
+    public interface IFileSortingRepository
+    {
+        /// <summary>
+        /// Saves the result.
+        /// </summary>
+        /// <param name="result">The result.</param>
+        /// <param name="cancellationToken">The cancellation token.</param>
+        /// <returns>Task.</returns>
+        Task SaveResult(FileSortingResult result, CancellationToken cancellationToken);
+
+        /// <summary>
+        /// Gets the results.
+        /// </summary>
+        /// <param name="query">The query.</param>
+        /// <returns>IEnumerable{FileSortingResult}.</returns>
+        IEnumerable<FileSortingResult> GetResults(FileSortingResultQuery query);
+    }
+}

+ 6 - 0
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -206,6 +206,12 @@
     <Compile Include="..\MediaBrowser.Model\Extensions\ModelExtensions.cs">
     <Compile Include="..\MediaBrowser.Model\Extensions\ModelExtensions.cs">
       <Link>Extensions\ModelExtensions.cs</Link>
       <Link>Extensions\ModelExtensions.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\FileSorting\FileSortingResult.cs">
+      <Link>FileSorting\FileSortingResult.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\FileSorting\FileSortingResultQuery.cs">
+      <Link>FileSorting\FileSortingResultQuery.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Games\GameSystem.cs">
     <Compile Include="..\MediaBrowser.Model\Games\GameSystem.cs">
       <Link>Games\GameSystem.cs</Link>
       <Link>Games\GameSystem.cs</Link>
     </Compile>
     </Compile>

+ 6 - 0
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -193,6 +193,12 @@
     <Compile Include="..\MediaBrowser.Model\Extensions\ModelExtensions.cs">
     <Compile Include="..\MediaBrowser.Model\Extensions\ModelExtensions.cs">
       <Link>Extensions\ModelExtensions.cs</Link>
       <Link>Extensions\ModelExtensions.cs</Link>
     </Compile>
     </Compile>
+    <Compile Include="..\MediaBrowser.Model\FileSorting\FileSortingResult.cs">
+      <Link>FileSorting\FileSortingResult.cs</Link>
+    </Compile>
+    <Compile Include="..\MediaBrowser.Model\FileSorting\FileSortingResultQuery.cs">
+      <Link>FileSorting\FileSortingResultQuery.cs</Link>
+    </Compile>
     <Compile Include="..\MediaBrowser.Model\Games\GameSystem.cs">
     <Compile Include="..\MediaBrowser.Model\Games\GameSystem.cs">
       <Link>Games\GameSystem.cs</Link>
       <Link>Games\GameSystem.cs</Link>
     </Compile>
     </Compile>

+ 45 - 0
MediaBrowser.Model/FileSorting/FileSortingResult.cs

@@ -0,0 +1,45 @@
+using System;
+
+namespace MediaBrowser.Model.FileSorting
+{
+    public class FileSortingResult
+    {
+        /// <summary>
+        /// Gets or sets the original path.
+        /// </summary>
+        /// <value>The original path.</value>
+        public string OriginalPath { get; set; }
+
+        /// <summary>
+        /// Gets or sets the target path.
+        /// </summary>
+        /// <value>The target path.</value>
+        public string TargetPath { get; set; }
+
+        /// <summary>
+        /// Gets or sets the date.
+        /// </summary>
+        /// <value>The date.</value>
+        public DateTime Date { get; set; }
+
+        /// <summary>
+        /// Gets or sets the error message.
+        /// </summary>
+        /// <value>The error message.</value>
+        public string ErrorMessage { get; set; }
+
+        /// <summary>
+        /// Gets or sets the status.
+        /// </summary>
+        /// <value>The status.</value>
+        public FileSortingStatus Status { get; set; }
+    }
+
+    public enum FileSortingStatus
+    {
+        Success,
+        Failure,
+        SkippedExisting,
+        SkippedTrial
+    }
+}

+ 18 - 0
MediaBrowser.Model/FileSorting/FileSortingResultQuery.cs

@@ -0,0 +1,18 @@
+
+namespace MediaBrowser.Model.FileSorting
+{
+    public class FileSortingResultQuery
+    {
+        /// <summary>
+        /// Skips over a given number of items within the results. Use for paging.
+        /// </summary>
+        /// <value>The start index.</value>
+        public int? StartIndex { get; set; }
+
+        /// <summary>
+        /// The maximum number of items to return
+        /// </summary>
+        /// <value>The limit.</value>
+        public int? Limit { get; set; }
+    }
+}

+ 2 - 0
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -71,6 +71,8 @@
     <Compile Include="Dto\ItemCounts.cs" />
     <Compile Include="Dto\ItemCounts.cs" />
     <Compile Include="Dto\ItemIndex.cs" />
     <Compile Include="Dto\ItemIndex.cs" />
     <Compile Include="Entities\PackageReviewInfo.cs" />
     <Compile Include="Entities\PackageReviewInfo.cs" />
+    <Compile Include="FileSorting\FileSortingResult.cs" />
+    <Compile Include="FileSorting\FileSortingResultQuery.cs" />
     <Compile Include="LiveTv\ChannelInfoDto.cs" />
     <Compile Include="LiveTv\ChannelInfoDto.cs" />
     <Compile Include="LiveTv\ChannelQuery.cs" />
     <Compile Include="LiveTv\ChannelQuery.cs" />
     <Compile Include="LiveTv\ProgramInfoDto.cs" />
     <Compile Include="LiveTv\ProgramInfoDto.cs" />

+ 5 - 7
MediaBrowser.Server.Implementations/FileSorting/SortingScheduledTask.cs

@@ -2,6 +2,7 @@
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Common.ScheduledTasks;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -16,13 +17,15 @@ namespace MediaBrowser.Server.Implementations.FileSorting
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
         private readonly IFileSystem _fileSystem;
         private readonly IFileSystem _fileSystem;
+        private readonly IFileSortingRepository _iFileSortingRepository;
 
 
-        public SortingScheduledTask(IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem)
+        public SortingScheduledTask(IServerConfigurationManager config, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem, IFileSortingRepository iFileSortingRepository)
         {
         {
             _config = config;
             _config = config;
             _logger = logger;
             _logger = logger;
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
+            _iFileSortingRepository = iFileSortingRepository;
         }
         }
 
 
         public string Name
         public string Name
@@ -42,12 +45,7 @@ namespace MediaBrowser.Server.Implementations.FileSorting
 
 
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
         {
         {
-            return Task.Run(() => SortFiles(cancellationToken, progress), cancellationToken);
-        }
-
-        private void SortFiles(CancellationToken cancellationToken, IProgress<double> progress)
-        {
-            new TvFileSorter(_libraryManager, _logger, _fileSystem).Sort(_config.Configuration.FileSortingOptions, cancellationToken, progress);
+            return new TvFileSorter(_libraryManager, _logger, _fileSystem, _iFileSortingRepository).Sort(_config.Configuration.FileSortingOptions, cancellationToken, progress);
         }
         }
 
 
         public IEnumerable<ITaskTrigger> GetDefaultTriggers()
         public IEnumerable<ITaskTrigger> GetDefaultTriggers()

+ 110 - 18
MediaBrowser.Server.Implementations/FileSorting/TvFileSorter.cs

@@ -1,10 +1,12 @@
 using MediaBrowser.Common.IO;
 using MediaBrowser.Common.IO;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Entities.TV;
 using MediaBrowser.Controller.Library;
 using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Controller.Resolvers;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Configuration;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.FileSorting;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.Logging;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
@@ -12,6 +14,7 @@ using System.Globalization;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Threading;
 using System.Threading;
+using System.Threading.Tasks;
 
 
 namespace MediaBrowser.Server.Implementations.FileSorting
 namespace MediaBrowser.Server.Implementations.FileSorting
 {
 {
@@ -20,26 +23,29 @@ namespace MediaBrowser.Server.Implementations.FileSorting
         private readonly ILibraryManager _libraryManager;
         private readonly ILibraryManager _libraryManager;
         private readonly ILogger _logger;
         private readonly ILogger _logger;
         private readonly IFileSystem _fileSystem;
         private readonly IFileSystem _fileSystem;
+        private readonly IFileSortingRepository _iFileSortingRepository;
 
 
         private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
         private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
-        
-        public TvFileSorter(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem)
+
+        public TvFileSorter(ILibraryManager libraryManager, ILogger logger, IFileSystem fileSystem, IFileSortingRepository iFileSortingRepository)
         {
         {
             _libraryManager = libraryManager;
             _libraryManager = libraryManager;
             _logger = logger;
             _logger = logger;
             _fileSystem = fileSystem;
             _fileSystem = fileSystem;
+            _iFileSortingRepository = iFileSortingRepository;
         }
         }
 
 
-        public void Sort(FileSortingOptions options, CancellationToken cancellationToken, IProgress<double> progress)
+        public async Task Sort(FileSortingOptions options, CancellationToken cancellationToken, IProgress<double> progress)
         {
         {
             var minFileBytes = options.MinFileSizeMb * 1024 * 1024;
             var minFileBytes = options.MinFileSizeMb * 1024 * 1024;
 
 
-            var eligibleFiles = options.TvWatchLocations.SelectMany(GetEligibleFiles)
+            var eligibleFiles = options.TvWatchLocations.SelectMany(GetFilesToSort)
+                .OrderBy(_fileSystem.GetCreationTimeUtc)
                 .Where(i => EntityResolutionHelper.IsVideoFile(i.FullName) && i.Length >= minFileBytes)
                 .Where(i => EntityResolutionHelper.IsVideoFile(i.FullName) && i.Length >= minFileBytes)
                 .ToList();
                 .ToList();
 
 
             progress.Report(10);
             progress.Report(10);
-            
+
             if (eligibleFiles.Count > 0)
             if (eligibleFiles.Count > 0)
             {
             {
                 var allSeries = _libraryManager.RootFolder
                 var allSeries = _libraryManager.RootFolder
@@ -48,16 +54,16 @@ namespace MediaBrowser.Server.Implementations.FileSorting
                     .ToList();
                     .ToList();
 
 
                 var numComplete = 0;
                 var numComplete = 0;
-                
+
                 foreach (var file in eligibleFiles)
                 foreach (var file in eligibleFiles)
                 {
                 {
-                    SortFile(file.FullName, options, allSeries);
+                    await SortFile(file.FullName, options, allSeries).ConfigureAwait(false);
 
 
                     numComplete++;
                     numComplete++;
                     double percent = numComplete;
                     double percent = numComplete;
                     percent /= eligibleFiles.Count;
                     percent /= eligibleFiles.Count;
 
 
-                    progress.Report(100 * percent);
+                    progress.Report(10 + (89 * percent));
                 }
                 }
             }
             }
 
 
@@ -83,7 +89,12 @@ namespace MediaBrowser.Server.Implementations.FileSorting
             progress.Report(100);
             progress.Report(100);
         }
         }
 
 
-        private IEnumerable<FileInfo> GetEligibleFiles(string path)
+        /// <summary>
+        /// Gets the eligible files.
+        /// </summary>
+        /// <param name="path">The path.</param>
+        /// <returns>IEnumerable{FileInfo}.</returns>
+        private IEnumerable<FileInfo> GetFilesToSort(string path)
         {
         {
             try
             try
             {
             {
@@ -95,14 +106,26 @@ namespace MediaBrowser.Server.Implementations.FileSorting
             {
             {
                 _logger.ErrorException("Error getting files from {0}", ex, path);
                 _logger.ErrorException("Error getting files from {0}", ex, path);
 
 
-                return new List<FileInfo>(); 
+                return new List<FileInfo>();
             }
             }
         }
         }
 
 
-        private void SortFile(string path, FileSortingOptions options, IEnumerable<Series> allSeries)
+        /// <summary>
+        /// Sorts the file.
+        /// </summary>
+        /// <param name="path">The path.</param>
+        /// <param name="options">The options.</param>
+        /// <param name="allSeries">All series.</param>
+        private Task SortFile(string path, FileSortingOptions options, IEnumerable<Series> allSeries)
         {
         {
             _logger.Info("Sorting file {0}", path);
             _logger.Info("Sorting file {0}", path);
 
 
+            var result = new FileSortingResult
+            {
+                Date = DateTime.UtcNow,
+                OriginalPath = path
+            };
+
             var seriesName = TVUtils.GetSeriesNameFromEpisodeFile(path);
             var seriesName = TVUtils.GetSeriesNameFromEpisodeFile(path);
 
 
             if (!string.IsNullOrEmpty(seriesName))
             if (!string.IsNullOrEmpty(seriesName))
@@ -118,31 +141,55 @@ namespace MediaBrowser.Server.Implementations.FileSorting
                     {
                     {
                         _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, season, episode);
                         _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, season, episode);
 
 
-                        SortFile(path, seriesName, season.Value, episode.Value, options, allSeries);
+                        SortFile(path, seriesName, season.Value, episode.Value, options, allSeries, result);
                     }
                     }
                     else
                     else
                     {
                     {
-                        _logger.Warn("Unable to determine episode number from {0}", path);
+                        var msg = string.Format("Unable to determine episode number from {0}", path);
+                        result.Status = FileSortingStatus.Failure;
+                        result.ErrorMessage = msg;
+                        _logger.Warn(msg);
                     }
                     }
                 }
                 }
                 else
                 else
                 {
                 {
-                    _logger.Warn("Unable to determine season number from {0}", path);
+                    var msg = string.Format("Unable to determine season number from {0}", path);
+                    result.Status = FileSortingStatus.Failure;
+                    result.ErrorMessage = msg;
+                    _logger.Warn(msg);
                 }
                 }
             }
             }
             else
             else
             {
             {
-                _logger.Warn("Unable to determine series name from {0}", path);
+                var msg = string.Format("Unable to determine series name from {0}", path);
+                result.Status = FileSortingStatus.Failure;
+                result.ErrorMessage = msg;
+                _logger.Warn(msg);
             }
             }
+
+            return LogResult(result);
         }
         }
 
 
-        private void SortFile(string path, string seriesName, int seasonNumber, int episodeNumber, FileSortingOptions options, IEnumerable<Series> allSeries)
+        /// <summary>
+        /// Sorts the file.
+        /// </summary>
+        /// <param name="path">The path.</param>
+        /// <param name="seriesName">Name of the series.</param>
+        /// <param name="seasonNumber">The season number.</param>
+        /// <param name="episodeNumber">The episode number.</param>
+        /// <param name="options">The options.</param>
+        /// <param name="allSeries">All series.</param>
+        /// <param name="result">The result.</param>
+        private void SortFile(string path, string seriesName, int seasonNumber, int episodeNumber, FileSortingOptions options, IEnumerable<Series> allSeries, FileSortingResult result)
         {
         {
             var series = GetMatchingSeries(seriesName, allSeries);
             var series = GetMatchingSeries(seriesName, allSeries);
 
 
             if (series == null)
             if (series == null)
             {
             {
-                _logger.Warn("Unable to find series in library matching name {0}", seriesName);
+                var msg = string.Format("Unable to find series in library matching name {0}", seriesName);
+                result.Status = FileSortingStatus.Failure;
+                result.ErrorMessage = msg;
+                _logger.Warn(msg);
                 return;
                 return;
             }
             }
 
 
@@ -153,13 +200,58 @@ namespace MediaBrowser.Server.Implementations.FileSorting
 
 
             if (string.IsNullOrEmpty(newPath))
             if (string.IsNullOrEmpty(newPath))
             {
             {
-                _logger.Warn("Unable to sort {0} because target path could not be found.", path);
+                var msg = string.Format("Unable to sort {0} because target path could not be determined.", path);
+                result.Status = FileSortingStatus.Failure;
+                result.ErrorMessage = msg;
+                _logger.Warn(msg);
                 return;
                 return;
             }
             }
 
 
             _logger.Info("Sorting file {0} to new path {1}", path, newPath);
             _logger.Info("Sorting file {0} to new path {1}", path, newPath);
+            result.TargetPath = newPath;
+
+            if (options.EnableTrialMode)
+            {
+                result.Status = FileSortingStatus.SkippedTrial;
+                return;
+            }
+
+            if (!options.OverwriteExistingEpisodes && File.Exists(result.TargetPath))
+            {
+                result.Status = FileSortingStatus.SkippedExisting;
+                return;
+            }
+
+            PerformFileSorting(options, result);
+        }
+
+        /// <summary>
+        /// Performs the file sorting.
+        /// </summary>
+        /// <param name="options">The options.</param>
+        /// <param name="result">The result.</param>
+        private void PerformFileSorting(FileSortingOptions options, FileSortingResult result)
+        {
         }
         }
 
 
+        /// <summary>
+        /// Logs the result.
+        /// </summary>
+        /// <param name="result">The result.</param>
+        /// <returns>Task.</returns>
+        private Task LogResult(FileSortingResult result)
+        {
+            return _iFileSortingRepository.SaveResult(result, CancellationToken.None);
+        }
+
+        /// <summary>
+        /// Gets the new path.
+        /// </summary>
+        /// <param name="series">The series.</param>
+        /// <param name="seasonNumber">The season number.</param>
+        /// <param name="episodeNumber">The episode number.</param>
+        /// <param name="options">The options.</param>
+        /// <returns>System.String.</returns>
         private string GetNewPath(Series series, int seasonNumber, int episodeNumber, FileSortingOptions options)
         private string GetNewPath(Series series, int seasonNumber, int episodeNumber, FileSortingOptions options)
         {
         {
             var currentEpisodes = series.RecursiveChildren.OfType<Episode>()
             var currentEpisodes = series.RecursiveChildren.OfType<Episode>()

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

@@ -179,6 +179,7 @@
     <Compile Include="News\NewsService.cs" />
     <Compile Include="News\NewsService.cs" />
     <Compile Include="Persistence\SqliteChapterRepository.cs" />
     <Compile Include="Persistence\SqliteChapterRepository.cs" />
     <Compile Include="Persistence\SqliteExtensions.cs" />
     <Compile Include="Persistence\SqliteExtensions.cs" />
+    <Compile Include="Persistence\SqliteFileSortingRepository.cs" />
     <Compile Include="Persistence\SqliteMediaStreamsRepository.cs" />
     <Compile Include="Persistence\SqliteMediaStreamsRepository.cs" />
     <Compile Include="Persistence\SqliteNotificationsRepository.cs" />
     <Compile Include="Persistence\SqliteNotificationsRepository.cs" />
     <Compile Include="Persistence\SqliteProviderInfoRepository.cs" />
     <Compile Include="Persistence\SqliteProviderInfoRepository.cs" />

+ 21 - 0
MediaBrowser.Server.Implementations/Persistence/SqliteFileSortingRepository.cs

@@ -0,0 +1,21 @@
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Model.FileSorting;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Persistence
+{
+    public class SqliteFileSortingRepository : IFileSortingRepository
+    {
+        public Task SaveResult(FileSortingResult result, CancellationToken cancellationToken)
+        {
+            return Task.FromResult(true);
+        }
+
+        public IEnumerable<FileSortingResult> GetResults(FileSortingResultQuery query)
+        {
+            return new List<FileSortingResult>();
+        }
+    }
+}

+ 4 - 0
MediaBrowser.ServerApplication/ApplicationHost.cs

@@ -170,6 +170,7 @@ namespace MediaBrowser.ServerApplication
         internal IDisplayPreferencesRepository DisplayPreferencesRepository { get; set; }
         internal IDisplayPreferencesRepository DisplayPreferencesRepository { get; set; }
         internal IItemRepository ItemRepository { get; set; }
         internal IItemRepository ItemRepository { get; set; }
         private INotificationsRepository NotificationsRepository { get; set; }
         private INotificationsRepository NotificationsRepository { get; set; }
+        private IFileSortingRepository FileSortingRepository { get; set; }
 
 
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="ApplicationHost"/> class.
         /// Initializes a new instance of the <see cref="ApplicationHost"/> class.
@@ -252,6 +253,9 @@ namespace MediaBrowser.ServerApplication
             ItemRepository = new SqliteItemRepository(ApplicationPaths, JsonSerializer, LogManager);
             ItemRepository = new SqliteItemRepository(ApplicationPaths, JsonSerializer, LogManager);
             RegisterSingleInstance(ItemRepository);
             RegisterSingleInstance(ItemRepository);
 
 
+            FileSortingRepository = new SqliteFileSortingRepository();
+            RegisterSingleInstance(FileSortingRepository);
+
             UserManager = new UserManager(Logger, ServerConfigurationManager, UserRepository);
             UserManager = new UserManager(Logger, ServerConfigurationManager, UserRepository);
             RegisterSingleInstance(UserManager);
             RegisterSingleInstance(UserManager);