mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Handling strongly typed options and adding a config get
This commit is contained in:
parent
9ae846f88a
commit
1929994128
@ -98,6 +98,7 @@ namespace Kyoo.Authentication
|
||||
services.Configure<PermissionOption>(_configuration.GetSection(PermissionOption.Path));
|
||||
services.Configure<CertificateOption>(_configuration.GetSection(CertificateOption.Path));
|
||||
services.Configure<AuthenticationOption>(_configuration.GetSection(AuthenticationOption.Path));
|
||||
services.AddConfiguration<AuthenticationOption>(AuthenticationOption.Path);
|
||||
|
||||
|
||||
List<Client> clients = new();
|
||||
|
91
Kyoo.Common/Models/ConfigurationReference.cs
Normal file
91
Kyoo.Common/Models/ConfigurationReference.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Kyoo.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// A class given information about a strongly typed configuration.
|
||||
/// </summary>
|
||||
public class ConfigurationReference
|
||||
{
|
||||
/// <summary>
|
||||
/// The path of the resource (separated by ':')
|
||||
/// </summary>
|
||||
public string Path { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of the resource.
|
||||
/// </summary>
|
||||
public Type Type { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ConfigurationReference"/> using a given path and type.
|
||||
/// This method does not create sub configuration resources. Please see <see cref="CreateReference"/>
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the resource (separated by ':' or "__")</param>
|
||||
/// <param name="type">The type of the resource</param>
|
||||
/// <seealso cref="CreateReference"/>
|
||||
public ConfigurationReference(string path, Type type)
|
||||
{
|
||||
Path = path;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the list of configuration reference a type has.
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// The base path of the type (separated by ':' or "__". If empty, it will start at root)
|
||||
/// </param>
|
||||
/// <param name="type">The type of the object</param>
|
||||
/// <returns>The list of configuration reference a type has.</returns>
|
||||
public static IEnumerable<ConfigurationReference> CreateReference(string path, [NotNull] Type type)
|
||||
{
|
||||
if (type == null)
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
|
||||
List<ConfigurationReference> ret = new()
|
||||
{
|
||||
new ConfigurationReference(path, type)
|
||||
};
|
||||
|
||||
|
||||
if (!type.IsClass || type.AssemblyQualifiedName?.StartsWith("System") == true)
|
||||
return ret;
|
||||
|
||||
Type enumerable = Utility.GetGenericDefinition(type, typeof(IEnumerable<>));
|
||||
Type dictionary = Utility.GetGenericDefinition(type, typeof(IDictionary<,>));
|
||||
Type dictionaryKey = dictionary?.GetGenericArguments()[0];
|
||||
|
||||
if (dictionary != null && dictionaryKey == typeof(string))
|
||||
ret.AddRange(CreateReference($"{path}:{type.Name}:*", dictionary.GetGenericArguments()[1]));
|
||||
else if (dictionary != null && dictionaryKey == typeof(int))
|
||||
ret.AddRange(CreateReference($"{path}:{type.Name}:", dictionary.GetGenericArguments()[1]));
|
||||
else if (enumerable != null)
|
||||
ret.AddRange(CreateReference($"{path}:{type.Name}:", enumerable.GetGenericArguments()[0]));
|
||||
else
|
||||
{
|
||||
foreach (PropertyInfo child in type.GetProperties())
|
||||
ret.AddRange(CreateReference($"{path}:{child.Name}", child.PropertyType));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the list of configuration reference a type has.
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// The base path of the type (separated by ':' or "__". If empty, it will start at root)
|
||||
/// </param>
|
||||
/// <typeparam name="T">The type of the object</typeparam>
|
||||
/// <returns>The list of configuration reference a type has.</returns>
|
||||
public static IEnumerable<ConfigurationReference> CreateReference<T>(string path)
|
||||
{
|
||||
return CreateReference(path, typeof(T));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@ -64,10 +66,20 @@ namespace Kyoo
|
||||
return services.AddRepository<T2>(lifetime);
|
||||
}
|
||||
|
||||
public static IServiceCollection AddConfiguration<T>(this IServiceCollection services, IConfiguration config, string path)
|
||||
/// <summary>
|
||||
/// Add an editable configuration to the editable configuration list
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection to edit</param>
|
||||
/// <param name="path">The root path of the editable configuration. It should not be a nested type.</param>
|
||||
/// <typeparam name="T">The type of the configuration</typeparam>
|
||||
/// <returns>The given service collection is returned.</returns>
|
||||
public static IServiceCollection AddConfiguration<T>(this IServiceCollection services, string path)
|
||||
where T : class
|
||||
{
|
||||
services.Configure<T>(config.GetSection(path));
|
||||
services.AddSingleton<ConfigReference>(new ConfigReference(path, typeof(T)));
|
||||
if (services.Any(x => x.ServiceType == typeof(T)))
|
||||
return services;
|
||||
foreach (ConfigurationReference confRef in ConfigurationReference.CreateReference<T>(path))
|
||||
services.AddSingleton(confRef);
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -15,15 +19,22 @@ namespace Kyoo.Api
|
||||
/// <summary>
|
||||
/// The configuration to retrieve and edit.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _config;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The strongly typed list of options
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, Type> _references;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="ConfigurationApi"/> using the given configuration.
|
||||
/// </summary>
|
||||
/// <param name="config">The configuration to use.</param>
|
||||
public ConfigurationApi(IConfiguration config)
|
||||
/// <param name="configuration">The configuration to use.</param>
|
||||
/// <param name="references">The strongly typed option list.</param>
|
||||
public ConfigurationApi(IConfiguration configuration, IEnumerable<ConfigurationReference> references)
|
||||
{
|
||||
_config = config;
|
||||
_configuration = configuration;
|
||||
_references = references.ToDictionary(x => x.Path, x => x.Type, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -35,7 +46,16 @@ namespace Kyoo.Api
|
||||
[Permission(nameof(ConfigurationApi), Kind.Admin)]
|
||||
public ActionResult<object> GetConfiguration(string slug)
|
||||
{
|
||||
return _config[slug];
|
||||
slug = slug.Replace("__", ":");
|
||||
// TODO handle lists and dictionaries.
|
||||
if (!_references.TryGetValue(slug, out Type type))
|
||||
return NotFound();
|
||||
object ret = _configuration.GetValue(type, slug);
|
||||
if (ret != null)
|
||||
return ret;
|
||||
object option = Activator.CreateInstance(type);
|
||||
_configuration.Bind(slug, option);
|
||||
return option;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user