aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/AppBase
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/AppBase')
-rw-r--r--Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs10
-rw-r--r--Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs75
-rw-r--r--Emby.Server.Implementations/AppBase/ConfigurationHelper.cs11
3 files changed, 63 insertions, 33 deletions
diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs
index 2adc1d6c3..6edfad575 100644
--- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs
+++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs
@@ -33,7 +33,7 @@ namespace Emby.Server.Implementations.AppBase
CachePath = cacheDirectoryPath;
WebPath = webDirectoryPath;
- DataPath = Path.Combine(ProgramDataPath, "data");
+ _dataPath = Directory.CreateDirectory(Path.Combine(ProgramDataPath, "data")).FullName;
}
/// <summary>
@@ -55,14 +55,10 @@ namespace Emby.Server.Implementations.AppBase
/// Gets the folder path to the data directory.
/// </summary>
/// <value>The data directory.</value>
- public string DataPath
- {
- get => _dataPath;
- private set => _dataPath = Directory.CreateDirectory(value).FullName;
- }
+ public string DataPath => _dataPath;
/// <inheritdoc />
- public string VirtualDataPath { get; } = "%AppDataPath%";
+ public string VirtualDataPath => "%AppDataPath%";
/// <summary>
/// Gets the image cache path.
diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
index d4a8268b9..d38535634 100644
--- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
+++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs
@@ -1,3 +1,5 @@
+#nullable disable
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -23,6 +25,11 @@ namespace Emby.Server.Implementations.AppBase
private readonly ConcurrentDictionary<string, object> _configurations = new ConcurrentDictionary<string, object>();
+ /// <summary>
+ /// The _configuration sync lock.
+ /// </summary>
+ private readonly object _configurationSyncLock = new object();
+
private ConfigurationStore[] _configurationStores = Array.Empty<ConfigurationStore>();
private IConfigurationFactory[] _configurationFactories = Array.Empty<IConfigurationFactory>();
@@ -32,11 +39,6 @@ namespace Emby.Server.Implementations.AppBase
private bool _configurationLoaded;
/// <summary>
- /// The _configuration sync lock.
- /// </summary>
- private readonly object _configurationSyncLock = new object();
-
- /// <summary>
/// The _configuration.
/// </summary>
private BaseApplicationConfiguration _configuration;
@@ -134,6 +136,33 @@ namespace Emby.Server.Implementations.AppBase
}
/// <summary>
+ /// Manually pre-loads a factory so that it is available pre system initialisation.
+ /// </summary>
+ /// <typeparam name="T">Class to register.</typeparam>
+ public virtual void RegisterConfiguration<T>()
+ where T : IConfigurationFactory
+ {
+ IConfigurationFactory factory = Activator.CreateInstance<T>();
+
+ if (_configurationFactories == null)
+ {
+ _configurationFactories = new[] { factory };
+ }
+ else
+ {
+ var oldLen = _configurationFactories.Length;
+ var arr = new IConfigurationFactory[oldLen + 1];
+ _configurationFactories.CopyTo(arr, 0);
+ arr[oldLen] = factory;
+ _configurationFactories = arr;
+ }
+
+ _configurationStores = _configurationFactories
+ .SelectMany(i => i.GetConfigurations())
+ .ToArray();
+ }
+
+ /// <summary>
/// Adds parts.
/// </summary>
/// <param name="factories">The configuration factories.</param>
@@ -270,25 +299,29 @@ namespace Emby.Server.Implementations.AppBase
/// <inheritdoc />
public object GetConfiguration(string key)
{
- return _configurations.GetOrAdd(key, k =>
- {
- var file = GetConfigurationFile(key);
+ return _configurations.GetOrAdd(
+ key,
+ (k, configurationManager) =>
+ {
+ var file = configurationManager.GetConfigurationFile(k);
- var configurationInfo = _configurationStores
- .FirstOrDefault(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase));
+ var configurationInfo = Array.Find(
+ configurationManager._configurationStores,
+ i => string.Equals(i.Key, k, StringComparison.OrdinalIgnoreCase));
- if (configurationInfo == null)
- {
- throw new ResourceNotFoundException("Configuration with key " + key + " not found.");
- }
+ if (configurationInfo == null)
+ {
+ throw new ResourceNotFoundException("Configuration with key " + k + " not found.");
+ }
- var configurationType = configurationInfo.ConfigurationType;
+ var configurationType = configurationInfo.ConfigurationType;
- lock (_configurationSyncLock)
- {
- return LoadConfiguration(file, configurationType);
- }
- });
+ lock (configurationManager._configurationSyncLock)
+ {
+ return configurationManager.LoadConfiguration(file, configurationType);
+ }
+ },
+ this);
}
private object LoadConfiguration(string path, Type configurationType)
@@ -308,7 +341,7 @@ namespace Emby.Server.Implementations.AppBase
}
catch (Exception ex)
{
- Logger.LogError(ex, "Error loading configuration file: {path}", path);
+ Logger.LogError(ex, "Error loading configuration file: {Path}", path);
return Activator.CreateInstance(configurationType);
}
diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
index 4c9ab33a7..0308a68e4 100644
--- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
+++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.IO;
using System.Linq;
@@ -35,7 +33,8 @@ namespace Emby.Server.Implementations.AppBase
}
catch (Exception)
{
- configuration = Activator.CreateInstance(type);
+ // Note: CreateInstance returns null for Nullable<T>, e.g. CreateInstance(typeof(int?)) returns null.
+ configuration = Activator.CreateInstance(type)!;
}
using var stream = new MemoryStream(buffer?.Length ?? 0);
@@ -48,10 +47,12 @@ namespace Emby.Server.Implementations.AppBase
// If the file didn't exist before, or if something has changed, re-save
if (buffer == null || !newBytes.AsSpan(0, newBytesLen).SequenceEqual(buffer))
{
- Directory.CreateDirectory(Path.GetDirectoryName(path));
+ var directory = Path.GetDirectoryName(path) ?? throw new ArgumentException($"Provided path ({path}) is not valid.", nameof(path));
+ Directory.CreateDirectory(directory);
// Save it after load in case we got new items
- using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
+ // use FileShare.None as this bypasses dotnet bug dotnet/runtime#42790 .
+ using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
{
fs.Write(newBytes, 0, newBytesLen);
}