|
@@ -0,0 +1,85 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.ComponentModel;
|
|
|
+using System.Globalization;
|
|
|
+
|
|
|
+namespace FastGithub.Configuration
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// 配置值绑定器
|
|
|
+ /// </summary>
|
|
|
+ static class ValueBinder
|
|
|
+ {
|
|
|
+ private static readonly Dictionary<Type, Binder> binders = new();
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 绑定转换器到指定类型
|
|
|
+ /// </summary>
|
|
|
+ /// <typeparam name="T"></typeparam>
|
|
|
+ /// <param name="reader"></param>
|
|
|
+ /// <param name="writer"></param>
|
|
|
+ public static void Bind<T>(Func<string, T?> reader, Func<T?, string?> writer)
|
|
|
+ {
|
|
|
+ binders[typeof(T)] = new Binder<T>(reader, writer);
|
|
|
+
|
|
|
+ var converterType = typeof(TypeConverter<>).MakeGenericType(typeof(T));
|
|
|
+ if (TypeDescriptor.GetConverter(typeof(T)).GetType() != converterType)
|
|
|
+ {
|
|
|
+ TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(converterType));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private abstract class Binder
|
|
|
+ {
|
|
|
+ public abstract object? Read(string value);
|
|
|
+
|
|
|
+ public abstract string? Write(object? value);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private class Binder<T> : Binder
|
|
|
+ {
|
|
|
+ private readonly Func<string, T?> reader;
|
|
|
+ private readonly Func<T?, string?> writer;
|
|
|
+
|
|
|
+ public Binder(Func<string, T?> reader, Func<T?, string?> writer)
|
|
|
+ {
|
|
|
+ this.reader = reader;
|
|
|
+ this.writer = writer;
|
|
|
+ }
|
|
|
+
|
|
|
+ public override object? Read(string value)
|
|
|
+ {
|
|
|
+ return this.reader(value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override string? Write(object? value)
|
|
|
+ {
|
|
|
+ return this.writer((T?)value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private class TypeConverter<T> : TypeConverter
|
|
|
+ {
|
|
|
+ public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
|
|
|
+ {
|
|
|
+ return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
|
|
|
+ {
|
|
|
+ return value is string stringVal && binders.TryGetValue(typeof(T), out var binder)
|
|
|
+ ? binder.Read(stringVal)
|
|
|
+ : base.ConvertFrom(context, culture, value);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
|
|
|
+ {
|
|
|
+ return destinationType == typeof(T) && binders.TryGetValue(destinationType, out var binder)
|
|
|
+ ? binder.Write(value)
|
|
|
+ : base.ConvertTo(context, culture, value, destinationType);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|