aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-29 00:10:11 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2016-10-29 00:10:11 -0400
commitce38e987910b4badb4c40844786449458b2d3229 (patch)
treefda30efcbfd2ebd70bd8348f19e76a8941f67e40 /MediaBrowser.Server.Implementations
parent9c6da95d6a5dce333fb66a58d73f7655f3a4d6ce (diff)
move common dependencies
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Logging/NLogger.cs224
-rw-r--r--MediaBrowser.Server.Implementations/Logging/NlogManager.cs264
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj7
-rw-r--r--MediaBrowser.Server.Implementations/Serialization/JsonSerializer.cs227
-rw-r--r--MediaBrowser.Server.Implementations/packages.config1
5 files changed, 723 insertions, 0 deletions
diff --git a/MediaBrowser.Server.Implementations/Logging/NLogger.cs b/MediaBrowser.Server.Implementations/Logging/NLogger.cs
new file mode 100644
index 000000000..11f41261a
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Logging/NLogger.cs
@@ -0,0 +1,224 @@
+using MediaBrowser.Model.Logging;
+using System;
+using System.Text;
+
+namespace MediaBrowser.Common.Implementations.Logging
+{
+ /// <summary>
+ /// Class NLogger
+ /// </summary>
+ public class NLogger : ILogger
+ {
+ /// <summary>
+ /// The _logger
+ /// </summary>
+ private readonly NLog.Logger _logger;
+
+ private readonly ILogManager _logManager;
+
+ /// <summary>
+ /// The _lock object
+ /// </summary>
+ private static readonly object LockObject = new object();
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NLogger" /> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="logManager">The log manager.</param>
+ public NLogger(string name, ILogManager logManager)
+ {
+ _logManager = logManager;
+ lock (LockObject)
+ {
+ _logger = NLog.LogManager.GetLogger(name);
+ }
+ }
+
+ /// <summary>
+ /// Infoes the specified message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="paramList">The param list.</param>
+ public void Info(string message, params object[] paramList)
+ {
+ _logger.Info(message, paramList);
+ }
+
+ /// <summary>
+ /// Errors the specified message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="paramList">The param list.</param>
+ public void Error(string message, params object[] paramList)
+ {
+ _logger.Error(message, paramList);
+ }
+
+ /// <summary>
+ /// Warns the specified message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="paramList">The param list.</param>
+ public void Warn(string message, params object[] paramList)
+ {
+ _logger.Warn(message, paramList);
+ }
+
+ /// <summary>
+ /// Debugs the specified message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="paramList">The param list.</param>
+ public void Debug(string message, params object[] paramList)
+ {
+ if (_logManager.LogSeverity == LogSeverity.Info)
+ {
+ return;
+ }
+
+ _logger.Debug(message, paramList);
+ }
+
+ /// <summary>
+ /// Logs the exception.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="exception">The exception.</param>
+ /// <param name="paramList">The param list.</param>
+ /// <exception cref="System.NotImplementedException"></exception>
+ public void ErrorException(string message, Exception exception, params object[] paramList)
+ {
+ LogException(LogSeverity.Error, message, exception, paramList);
+ }
+
+ /// <summary>
+ /// Logs the exception.
+ /// </summary>
+ /// <param name="level">The level.</param>
+ /// <param name="message">The message.</param>
+ /// <param name="exception">The exception.</param>
+ /// <param name="paramList">The param list.</param>
+ private void LogException(LogSeverity level, string message, Exception exception, params object[] paramList)
+ {
+ message = FormatMessage(message, paramList).Replace(Environment.NewLine, ". ");
+
+ var messageText = LogHelper.GetLogMessage(exception);
+
+ var prefix = _logManager.ExceptionMessagePrefix;
+
+ if (!string.IsNullOrWhiteSpace(prefix))
+ {
+ messageText.Insert(0, prefix);
+ }
+
+ LogMultiline(message, level, messageText);
+ }
+
+ /// <summary>
+ /// Formats the message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="paramList">The param list.</param>
+ /// <returns>System.String.</returns>
+ private static string FormatMessage(string message, params object[] paramList)
+ {
+ if (paramList != null)
+ {
+ for (var i = 0; i < paramList.Length; i++)
+ {
+ var obj = paramList[i];
+
+ message = message.Replace("{" + i + "}", (obj == null ? "null" : obj.ToString()));
+ }
+ }
+
+ return message;
+ }
+
+ /// <summary>
+ /// Logs the multiline.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="severity">The severity.</param>
+ /// <param name="additionalContent">Content of the additional.</param>
+ public void LogMultiline(string message, LogSeverity severity, StringBuilder additionalContent)
+ {
+ if (severity == LogSeverity.Debug && _logManager.LogSeverity == LogSeverity.Info)
+ {
+ return;
+ }
+
+ additionalContent.Insert(0, message + Environment.NewLine);
+
+ const char tabChar = '\t';
+
+ var text = additionalContent.ToString()
+ .Replace(Environment.NewLine, Environment.NewLine + tabChar)
+ .TrimEnd(tabChar);
+
+ if (text.EndsWith(Environment.NewLine))
+ {
+ text = text.Substring(0, text.LastIndexOf(Environment.NewLine, StringComparison.OrdinalIgnoreCase));
+ }
+
+ _logger.Log(GetLogLevel(severity), text);
+ }
+
+ /// <summary>
+ /// Gets the log level.
+ /// </summary>
+ /// <param name="severity">The severity.</param>
+ /// <returns>NLog.LogLevel.</returns>
+ private NLog.LogLevel GetLogLevel(LogSeverity severity)
+ {
+ switch (severity)
+ {
+ case LogSeverity.Debug:
+ return NLog.LogLevel.Debug;
+ case LogSeverity.Error:
+ return NLog.LogLevel.Error;
+ case LogSeverity.Warn:
+ return NLog.LogLevel.Warn;
+ case LogSeverity.Fatal:
+ return NLog.LogLevel.Fatal;
+ case LogSeverity.Info:
+ return NLog.LogLevel.Info;
+ default:
+ throw new ArgumentException("Unknown LogSeverity: " + severity.ToString());
+ }
+ }
+
+ /// <summary>
+ /// Logs the specified severity.
+ /// </summary>
+ /// <param name="severity">The severity.</param>
+ /// <param name="message">The message.</param>
+ /// <param name="paramList">The param list.</param>
+ public void Log(LogSeverity severity, string message, params object[] paramList)
+ {
+ _logger.Log(GetLogLevel(severity), message, paramList);
+ }
+
+ /// <summary>
+ /// Fatals the specified message.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="paramList">The param list.</param>
+ public void Fatal(string message, params object[] paramList)
+ {
+ _logger.Fatal(message, paramList);
+ }
+
+ /// <summary>
+ /// Fatals the exception.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ /// <param name="exception">The exception.</param>
+ /// <param name="paramList">The param list.</param>
+ public void FatalException(string message, Exception exception, params object[] paramList)
+ {
+ LogException(LogSeverity.Fatal, message, exception, paramList);
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Logging/NlogManager.cs b/MediaBrowser.Server.Implementations/Logging/NlogManager.cs
new file mode 100644
index 000000000..1bbcccd88
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Logging/NlogManager.cs
@@ -0,0 +1,264 @@
+using MediaBrowser.Model.Logging;
+using NLog;
+using NLog.Config;
+using NLog.Targets;
+using NLog.Targets.Wrappers;
+using System;
+using System.IO;
+using System.Linq;
+
+namespace MediaBrowser.Common.Implementations.Logging
+{
+ /// <summary>
+ /// Class NlogManager
+ /// </summary>
+ public class NlogManager : ILogManager
+ {
+ /// <summary>
+ /// Occurs when [logger loaded].
+ /// </summary>
+ public event EventHandler LoggerLoaded;
+ /// <summary>
+ /// Gets or sets the log directory.
+ /// </summary>
+ /// <value>The log directory.</value>
+ private string LogDirectory { get; set; }
+ /// <summary>
+ /// Gets or sets the log file prefix.
+ /// </summary>
+ /// <value>The log file prefix.</value>
+ private string LogFilePrefix { get; set; }
+ /// <summary>
+ /// Gets the log file path.
+ /// </summary>
+ /// <value>The log file path.</value>
+ public string LogFilePath { get; private set; }
+
+ /// <summary>
+ /// Gets or sets the exception message prefix.
+ /// </summary>
+ /// <value>The exception message prefix.</value>
+ public string ExceptionMessagePrefix { get; set; }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="NlogManager" /> class.
+ /// </summary>
+ /// <param name="logDirectory">The log directory.</param>
+ /// <param name="logFileNamePrefix">The log file name prefix.</param>
+ public NlogManager(string logDirectory, string logFileNamePrefix)
+ {
+ LogDirectory = logDirectory;
+ LogFilePrefix = logFileNamePrefix;
+
+ LogManager.Configuration = new LoggingConfiguration ();
+ }
+
+ private LogSeverity _severity = LogSeverity.Debug;
+ public LogSeverity LogSeverity
+ {
+ get
+ {
+ return _severity;
+ }
+ set
+ {
+ var changed = _severity != value;
+
+ _severity = value;
+
+ if (changed)
+ {
+ UpdateLogLevel(value);
+ }
+ }
+ }
+
+ private void UpdateLogLevel(LogSeverity newLevel)
+ {
+ var level = GetLogLevel(newLevel);
+
+ var rules = LogManager.Configuration.LoggingRules;
+
+ foreach (var rule in rules)
+ {
+ if (!rule.IsLoggingEnabledForLevel(level))
+ {
+ rule.EnableLoggingForLevel(level);
+ }
+ foreach (var lev in rule.Levels.ToArray())
+ {
+ if (lev < level)
+ {
+ rule.DisableLoggingForLevel(lev);
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Adds the file target.
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="level">The level.</param>
+ private void AddFileTarget(string path, LogSeverity level)
+ {
+ RemoveTarget("ApplicationLogFileWrapper");
+
+ var wrapper = new AsyncTargetWrapper ();
+ wrapper.Name = "ApplicationLogFileWrapper";
+
+ var logFile = new FileTarget
+ {
+ FileName = path,
+ Layout = "${longdate} ${level} ${logger}: ${message}"
+ };
+
+ logFile.Name = "ApplicationLogFile";
+
+ wrapper.WrappedTarget = logFile;
+
+ AddLogTarget(wrapper, level);
+ }
+
+ /// <summary>
+ /// Adds the log target.
+ /// </summary>
+ /// <param name="target">The target.</param>
+ /// <param name="level">The level.</param>
+ public void AddLogTarget(Target target, LogSeverity level)
+ {
+ var config = LogManager.Configuration;
+ config.AddTarget(target.Name, target);
+
+ var rule = new LoggingRule("*", GetLogLevel(level), target);
+ config.LoggingRules.Add(rule);
+
+ LogManager.Configuration = config;
+ }
+
+ /// <summary>
+ /// Removes the target.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ public void RemoveTarget(string name)
+ {
+ var config = LogManager.Configuration;
+
+ var target = config.FindTargetByName(name);
+
+ if (target != null)
+ {
+ foreach (var rule in config.LoggingRules.ToList())
+ {
+ var contains = rule.Targets.Contains(target);
+
+ rule.Targets.Remove(target);
+
+ if (contains)
+ {
+ config.LoggingRules.Remove(rule);
+ }
+ }
+
+ config.RemoveTarget(name);
+ LogManager.Configuration = config;
+ }
+ }
+
+ /// <summary>
+ /// Gets the logger.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <returns>ILogger.</returns>
+ public Model.Logging.ILogger GetLogger(string name)
+ {
+ return new NLogger(name, this);
+ }
+
+ /// <summary>
+ /// Gets the log level.
+ /// </summary>
+ /// <param name="severity">The severity.</param>
+ /// <returns>LogLevel.</returns>
+ /// <exception cref="System.ArgumentException">Unrecognized LogSeverity</exception>
+ private LogLevel GetLogLevel(LogSeverity severity)
+ {
+ switch (severity)
+ {
+ case LogSeverity.Debug:
+ return LogLevel.Debug;
+ case LogSeverity.Error:
+ return LogLevel.Error;
+ case LogSeverity.Fatal:
+ return LogLevel.Fatal;
+ case LogSeverity.Info:
+ return LogLevel.Info;
+ case LogSeverity.Warn:
+ return LogLevel.Warn;
+ default:
+ throw new ArgumentException("Unrecognized LogSeverity");
+ }
+ }
+
+ /// <summary>
+ /// Reloads the logger.
+ /// </summary>
+ /// <param name="level">The level.</param>
+ public void ReloadLogger(LogSeverity level)
+ {
+ LogFilePath = Path.Combine(LogDirectory, LogFilePrefix + "-" + decimal.Round(DateTime.Now.Ticks / 10000000) + ".txt");
+
+ Directory.CreateDirectory(Path.GetDirectoryName(LogFilePath));
+
+ AddFileTarget(LogFilePath, level);
+
+ LogSeverity = level;
+
+ if (LoggerLoaded != null)
+ {
+ try
+ {
+ LoggerLoaded(this, EventArgs.Empty);
+ }
+ catch (Exception ex)
+ {
+ GetLogger("Logger").ErrorException("Error in LoggerLoaded event", ex);
+ }
+ }
+ }
+
+ /// <summary>
+ /// Flushes this instance.
+ /// </summary>
+ public void Flush()
+ {
+ LogManager.Flush();
+ }
+
+
+ public void AddConsoleOutput()
+ {
+ RemoveTarget("ConsoleTargetWrapper");
+
+ var wrapper = new AsyncTargetWrapper ();
+ wrapper.Name = "ConsoleTargetWrapper";
+
+ var target = new ConsoleTarget()
+ {
+ Layout = "${level}, ${logger}, ${message}",
+ Error = false
+ };
+
+ target.Name = "ConsoleTarget";
+
+ wrapper.WrappedTarget = target;
+
+ AddLogTarget(wrapper, LogSeverity);
+ }
+
+ public void RemoveConsoleOutput()
+ {
+ RemoveTarget("ConsoleTargetWrapper");
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 854a9cecb..ec1fbb479 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -61,6 +61,10 @@
<HintPath>..\packages\Microsoft.IO.RecyclableMemoryStream.1.1.0.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll</HintPath>
<Private>True</Private>
</Reference>
+ <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
+ <HintPath>..\packages\NLog.4.3.10\lib\net45\NLog.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
<Reference Include="Patterns.Logging">
<HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath>
</Reference>
@@ -272,6 +276,8 @@
<Compile Include="LiveTv\TunerHosts\SatIp\TransmissionMode.cs" />
<Compile Include="LiveTv\TunerHosts\SatIp\Utils.cs" />
<Compile Include="Localization\LocalizationManager.cs" />
+ <Compile Include="Logging\NLogger.cs" />
+ <Compile Include="Logging\NlogManager.cs" />
<Compile Include="Logging\PatternsLogger.cs" />
<Compile Include="MediaEncoder\EncodingManager.cs" />
<Compile Include="Notifications\IConfigurableNotificationService.cs" />
@@ -281,6 +287,7 @@
<Compile Include="Persistence\IDbConnector.cs" />
<Compile Include="Persistence\MediaStreamColumns.cs" />
<Compile Include="Reflection\AssemblyInfo.cs" />
+ <Compile Include="Serialization\JsonSerializer.cs" />
<Compile Include="Social\SharingManager.cs" />
<Compile Include="Social\SharingRepository.cs" />
<Compile Include="Sorting\StartDateComparer.cs" />
diff --git a/MediaBrowser.Server.Implementations/Serialization/JsonSerializer.cs b/MediaBrowser.Server.Implementations/Serialization/JsonSerializer.cs
new file mode 100644
index 000000000..b9a03242c
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Serialization/JsonSerializer.cs
@@ -0,0 +1,227 @@
+using System;
+using System.IO;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Serialization;
+
+namespace MediaBrowser.Server.Implementations.Serialization
+{
+ /// <summary>
+ /// Provides a wrapper around third party json serialization.
+ /// </summary>
+ public class JsonSerializer : IJsonSerializer
+ {
+ private readonly IFileSystem _fileSystem;
+ private readonly ILogger _logger;
+
+ public JsonSerializer(IFileSystem fileSystem, ILogger logger)
+ {
+ _fileSystem = fileSystem;
+ _logger = logger;
+ Configure();
+ }
+
+ /// <summary>
+ /// Serializes to stream.
+ /// </summary>
+ /// <param name="obj">The obj.</param>
+ /// <param name="stream">The stream.</param>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ public void SerializeToStream(object obj, Stream stream)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException("obj");
+ }
+
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ ServiceStack.Text.JsonSerializer.SerializeToStream(obj, obj.GetType(), stream);
+ }
+
+ /// <summary>
+ /// Serializes to file.
+ /// </summary>
+ /// <param name="obj">The obj.</param>
+ /// <param name="file">The file.</param>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ public void SerializeToFile(object obj, string file)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException("obj");
+ }
+
+ if (string.IsNullOrEmpty(file))
+ {
+ throw new ArgumentNullException("file");
+ }
+
+ using (Stream stream = _fileSystem.GetFileStream(file, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
+ {
+ SerializeToStream(obj, stream);
+ }
+ }
+
+ private Stream OpenFile(string path)
+ {
+ _logger.Debug("Deserializing file {0}", path);
+ return new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 131072);
+ }
+
+ /// <summary>
+ /// Deserializes from file.
+ /// </summary>
+ /// <param name="type">The type.</param>
+ /// <param name="file">The file.</param>
+ /// <returns>System.Object.</returns>
+ /// <exception cref="System.ArgumentNullException">type</exception>
+ public object DeserializeFromFile(Type type, string file)
+ {
+ if (type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+
+ if (string.IsNullOrEmpty(file))
+ {
+ throw new ArgumentNullException("file");
+ }
+
+ using (Stream stream = OpenFile(file))
+ {
+ return DeserializeFromStream(stream, type);
+ }
+ }
+
+ /// <summary>
+ /// Deserializes from file.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="file">The file.</param>
+ /// <returns>``0.</returns>
+ /// <exception cref="System.ArgumentNullException">file</exception>
+ public T DeserializeFromFile<T>(string file)
+ where T : class
+ {
+ if (string.IsNullOrEmpty(file))
+ {
+ throw new ArgumentNullException("file");
+ }
+
+ using (Stream stream = OpenFile(file))
+ {
+ return DeserializeFromStream<T>(stream);
+ }
+ }
+
+ /// <summary>
+ /// Deserializes from stream.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="stream">The stream.</param>
+ /// <returns>``0.</returns>
+ /// <exception cref="System.ArgumentNullException">stream</exception>
+ public T DeserializeFromStream<T>(Stream stream)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ return ServiceStack.Text.JsonSerializer.DeserializeFromStream<T>(stream);
+ }
+
+ /// <summary>
+ /// Deserializes from string.
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ /// <param name="text">The text.</param>
+ /// <returns>``0.</returns>
+ /// <exception cref="System.ArgumentNullException">text</exception>
+ public T DeserializeFromString<T>(string text)
+ {
+ if (string.IsNullOrEmpty(text))
+ {
+ throw new ArgumentNullException("text");
+ }
+
+ return ServiceStack.Text.JsonSerializer.DeserializeFromString<T>(text);
+ }
+
+ /// <summary>
+ /// Deserializes from stream.
+ /// </summary>
+ /// <param name="stream">The stream.</param>
+ /// <param name="type">The type.</param>
+ /// <returns>System.Object.</returns>
+ /// <exception cref="System.ArgumentNullException">stream</exception>
+ public object DeserializeFromStream(Stream stream, Type type)
+ {
+ if (stream == null)
+ {
+ throw new ArgumentNullException("stream");
+ }
+
+ if (type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+
+ return ServiceStack.Text.JsonSerializer.DeserializeFromStream(type, stream);
+ }
+
+ /// <summary>
+ /// Configures this instance.
+ /// </summary>
+ private void Configure()
+ {
+ ServiceStack.Text.JsConfig.DateHandler = ServiceStack.Text.DateHandler.ISO8601;
+ ServiceStack.Text.JsConfig.ExcludeTypeInfo = true;
+ ServiceStack.Text.JsConfig.IncludeNullValues = false;
+ ServiceStack.Text.JsConfig.AlwaysUseUtc = true;
+ ServiceStack.Text.JsConfig.AssumeUtc = true;
+ }
+
+ /// <summary>
+ /// Deserializes from string.
+ /// </summary>
+ /// <param name="json">The json.</param>
+ /// <param name="type">The type.</param>
+ /// <returns>System.Object.</returns>
+ /// <exception cref="System.ArgumentNullException">json</exception>
+ public object DeserializeFromString(string json, Type type)
+ {
+ if (string.IsNullOrEmpty(json))
+ {
+ throw new ArgumentNullException("json");
+ }
+
+ if (type == null)
+ {
+ throw new ArgumentNullException("type");
+ }
+
+ return ServiceStack.Text.JsonSerializer.DeserializeFromString(json, type);
+ }
+
+ /// <summary>
+ /// Serializes to string.
+ /// </summary>
+ /// <param name="obj">The obj.</param>
+ /// <returns>System.String.</returns>
+ /// <exception cref="System.ArgumentNullException">obj</exception>
+ public string SerializeToString(object obj)
+ {
+ if (obj == null)
+ {
+ throw new ArgumentNullException("obj");
+ }
+
+ return ServiceStack.Text.JsonSerializer.SerializeToString(obj, obj.GetType());
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config
index 522d2bbfd..223b61b2b 100644
--- a/MediaBrowser.Server.Implementations/packages.config
+++ b/MediaBrowser.Server.Implementations/packages.config
@@ -5,6 +5,7 @@
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
<package id="MediaBrowser.Naming" version="1.0.0.55" targetFramework="net45" />
<package id="Microsoft.IO.RecyclableMemoryStream" version="1.1.0.0" targetFramework="net46" />
+ <package id="NLog" version="4.3.10" targetFramework="net46" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
<package id="SimpleInjector" version="3.2.4" targetFramework="net46" />
<package id="SocketHttpListener" version="1.0.0.40" targetFramework="net45" />