diff --git a/FastGithub.Configuration/DomainConfig.cs b/FastGithub.Configuration/DomainConfig.cs index 988a53f..6059e36 100644 --- a/FastGithub.Configuration/DomainConfig.cs +++ b/FastGithub.Configuration/DomainConfig.cs @@ -1,4 +1,5 @@ using System; +using System.Net; namespace FastGithub.Configuration { @@ -26,7 +27,7 @@ namespace FastGithub.Configuration /// /// 使用的ip地址 /// - public string? IPAddress { get; init; } + public IPAddress? IPAddress { get; init; } /// /// 请求超时时长 @@ -59,6 +60,6 @@ namespace FastGithub.Configuration return Configuration.TlsSniPattern.Domain; } return new TlsSniPattern(this.TlsSniPattern); - } + } } } diff --git a/FastGithub.Configuration/FastGithubConfig.cs b/FastGithub.Configuration/FastGithubConfig.cs index bf929e5..5cfe02c 100644 --- a/FastGithub.Configuration/FastGithubConfig.cs +++ b/FastGithub.Configuration/FastGithubConfig.cs @@ -35,7 +35,7 @@ namespace FastGithub.Configuration var opt = options.CurrentValue; this.HttpProxyPort = opt.HttpProxyPort; - this.FallbackDns = ConvertToIPEndPoints(opt.FallbackDns).ToArray(); + this.FallbackDns = opt.FallbackDns; this.domainConfigs = ConvertDomainConfigs(opt.DomainConfigs); this.domainConfigCache = new ConcurrentDictionary(); @@ -49,27 +49,11 @@ namespace FastGithub.Configuration private void Update(FastGithubOptions options) { this.HttpProxyPort = options.HttpProxyPort; - this.FallbackDns = ConvertToIPEndPoints(options.FallbackDns).ToArray(); + this.FallbackDns = options.FallbackDns; this.domainConfigs = ConvertDomainConfigs(options.DomainConfigs); this.domainConfigCache = new ConcurrentDictionary(); } - /// - /// 转换为IPEndPoint - /// - /// - /// - private static IEnumerable ConvertToIPEndPoints(IEnumerable ipEndPoints) - { - foreach (var item in ipEndPoints) - { - if (IPEndPoint.TryParse(item, out var endPoint)) - { - yield return endPoint; - } - } - } - /// /// 配置转换 /// diff --git a/FastGithub.Configuration/FastGithubOptions.cs b/FastGithub.Configuration/FastGithubOptions.cs index 59ec188..a4af722 100644 --- a/FastGithub.Configuration/FastGithubOptions.cs +++ b/FastGithub.Configuration/FastGithubOptions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Net; namespace FastGithub.Configuration { @@ -16,7 +17,7 @@ namespace FastGithub.Configuration /// /// 回退的dns /// - public string[] FallbackDns { get; set; } = Array.Empty(); + public IPEndPoint[] FallbackDns { get; set; } = Array.Empty(); /// /// 代理的域名配置 diff --git a/FastGithub.Configuration/ServiceCollectionExtensions.cs b/FastGithub.Configuration/ServiceCollectionExtensions.cs index 7b44181..f3d4832 100644 --- a/FastGithub.Configuration/ServiceCollectionExtensions.cs +++ b/FastGithub.Configuration/ServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; +using System.Net; namespace FastGithub { @@ -17,6 +18,9 @@ namespace FastGithub /// public static IServiceCollection AddConfiguration(this IServiceCollection services) { + ValueBinder.Bind(val => IPAddress.Parse(val), val => val?.ToString()); + ValueBinder.Bind(val => IPEndPoint.Parse(val), val => val?.ToString()); + services.TryAddSingleton(); return services; } diff --git a/FastGithub.Configuration/ValueBinder.cs b/FastGithub.Configuration/ValueBinder.cs new file mode 100644 index 0000000..0ab0169 --- /dev/null +++ b/FastGithub.Configuration/ValueBinder.cs @@ -0,0 +1,85 @@ +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); + } + } + } +} diff --git a/FastGithub.Http/HttpClientHandler.cs b/FastGithub.Http/HttpClientHandler.cs index 808ca5a..a1001b5 100644 --- a/FastGithub.Http/HttpClientHandler.cs +++ b/FastGithub.Http/HttpClientHandler.cs @@ -181,9 +181,9 @@ namespace FastGithub.Http } else { - if (IPAddress.TryParse(this.domainConfig.IPAddress, out address)) + if (this.domainConfig.IPAddress != null) { - yield return new IPEndPoint(address, dnsEndPoint.Port); + yield return new IPEndPoint(this.domainConfig.IPAddress, dnsEndPoint.Port); } await foreach (var item in this.domainResolver.ResolveAllAsync(dnsEndPoint, cancellationToken))