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<PermissionOption>(_configuration.GetSection(PermissionOption.Path));
|
||||||
services.Configure<CertificateOption>(_configuration.GetSection(CertificateOption.Path));
|
services.Configure<CertificateOption>(_configuration.GetSection(CertificateOption.Path));
|
||||||
services.Configure<AuthenticationOption>(_configuration.GetSection(AuthenticationOption.Path));
|
services.Configure<AuthenticationOption>(_configuration.GetSection(AuthenticationOption.Path));
|
||||||
|
services.AddConfiguration<AuthenticationOption>(AuthenticationOption.Path);
|
||||||
|
|
||||||
|
|
||||||
List<Client> clients = new();
|
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;
|
||||||
|
using System.Linq;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
|
using Kyoo.Models;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
@ -64,10 +66,20 @@ namespace Kyoo
|
|||||||
return services.AddRepository<T2>(lifetime);
|
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));
|
if (services.Any(x => x.ServiceType == typeof(T)))
|
||||||
services.AddSingleton<ConfigReference>(new ConfigReference(path, typeof(T)));
|
return services;
|
||||||
|
foreach (ConfigurationReference confRef in ConfigurationReference.CreateReference<T>(path))
|
||||||
|
services.AddSingleton(confRef);
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Permissions;
|
using Kyoo.Models.Permissions;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
@ -15,15 +19,22 @@ namespace Kyoo.Api
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The configuration to retrieve and edit.
|
/// The configuration to retrieve and edit.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IConfiguration _config;
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The strongly typed list of options
|
||||||
|
/// </summary>
|
||||||
|
private readonly Dictionary<string, Type> _references;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new <see cref="ConfigurationApi"/> using the given configuration.
|
/// Create a new <see cref="ConfigurationApi"/> using the given configuration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config">The configuration to use.</param>
|
/// <param name="configuration">The configuration to use.</param>
|
||||||
public ConfigurationApi(IConfiguration config)
|
/// <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>
|
/// <summary>
|
||||||
@ -35,7 +46,16 @@ namespace Kyoo.Api
|
|||||||
[Permission(nameof(ConfigurationApi), Kind.Admin)]
|
[Permission(nameof(ConfigurationApi), Kind.Admin)]
|
||||||
public ActionResult<object> GetConfiguration(string slug)
|
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