using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; namespace FastGithub.Configuration { /// /// 配置值绑定器 /// static class ValueBinder { private static readonly Dictionary binders = new(); /// /// 绑定转换器到指定类型 /// /// /// /// public static void Bind(Func reader, Func writer) { binders[typeof(T)] = new Binder(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 : Binder { private readonly Func reader; private readonly Func writer; public Binder(Func reader, Func 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 : 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); } } } }