// ------------------------------------------------------------------------ // 版权信息 // 版权归百小僧及百签科技(广东)有限公司所有。 // 所有权利保留。 // 官方网站:https://baiqian.com // // 许可证信息 // 项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。 // 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。 // ------------------------------------------------------------------------ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; using System.Reflection; using System.Text; using ThingsGateway.Extension; namespace ThingsGateway.HttpRemote; /// /// HTTP 远程请求构建器 /// public sealed class HttpRemoteBuilder { /// /// 集合 /// internal IList>>? _httpContentConverterProviders; /// /// 集合 /// internal IList>>? _httpContentProcessorProviders; /// /// 集合 /// internal IList>>? _httpDeclarativeExtractors; /// /// 类型集合 /// internal HashSet? _httpDeclarativeTypes; /// /// 实现类型 /// internal Type? _objectContentConverterFactoryType; /// /// 添加 请求内容处理器 /// /// 支持多次调用。 /// 实例提供器 /// /// /// public HttpRemoteBuilder AddHttpContentProcessors(Func> configure) { // 空检查 ArgumentNullException.ThrowIfNull(configure); _httpContentProcessorProviders ??= new List>>(); _httpContentProcessorProviders.Add(configure); return this; } /// /// 添加 响应内容转换器 /// /// 支持多次调用。 /// 实例提供器 /// /// /// public HttpRemoteBuilder AddHttpContentConverters(Func> configure) { // 空检查 ArgumentNullException.ThrowIfNull(configure); _httpContentConverterProviders ??= new List>>(); _httpContentConverterProviders.Add(configure); return this; } /// /// 设置 对象内容转换器工厂 /// /// /// /// /// /// /// public HttpRemoteBuilder UseObjectContentConverterFactory() where TFactory : IObjectContentConverterFactory => UseObjectContentConverterFactory(typeof(TFactory)); /// /// 设置 对象内容转换器工厂 /// /// /// /// /// /// /// /// public HttpRemoteBuilder UseObjectContentConverterFactory(Type factoryType) { // 空检查 ArgumentNullException.ThrowIfNull(factoryType); // 检查类型是否实现了 IObjectContentConverterFactory 接口 if (!typeof(IObjectContentConverterFactory).IsAssignableFrom(factoryType)) { throw new ArgumentException( $"`{factoryType}` type is not assignable from `{typeof(IObjectContentConverterFactory)}`.", nameof(factoryType)); } _objectContentConverterFactoryType = factoryType; return this; } /// /// 添加 HTTP 声明式服务 /// /// /// /// /// /// /// public HttpRemoteBuilder AddHttpDeclarative() where TDeclarative : IHttpDeclarative => AddHttpDeclarative(typeof(TDeclarative)); /// /// 添加 HTTP 声明式服务 /// /// /// /// /// /// /// /// public HttpRemoteBuilder AddHttpDeclarative(Type declarativeType) { // 空检查 ArgumentNullException.ThrowIfNull(declarativeType); // 检查类型是否是接口且实现了 IHttpDeclarative 接口 if (!declarativeType.IsInterface || !typeof(IHttpDeclarative).IsAssignableFrom(declarativeType)) { throw new ArgumentException( $"`{declarativeType}` type is not assignable from `{typeof(IHttpDeclarative)}` or interface.", nameof(declarativeType)); } _httpDeclarativeTypes ??= []; _httpDeclarativeTypes.Add(declarativeType); return this; } /// /// 添加 HTTP 声明式服务 /// /// /// 集合 /// /// /// /// /// public HttpRemoteBuilder AddHttpDeclaratives(params IEnumerable declarativeTypes) { // 空检查 ArgumentNullException.ThrowIfNull(declarativeTypes); foreach (var declarativeType in declarativeTypes) { AddHttpDeclarative(declarativeType); } return this; } /// /// 扫描程序集并添加 HTTP 声明式服务 /// /// 集合 /// /// /// public HttpRemoteBuilder AddHttpDeclarativeFromAssemblies(params IEnumerable assemblies) { // 空检查 ArgumentNullException.ThrowIfNull(assemblies); AddHttpDeclaratives(assemblies.SelectMany(ass => (ass?.GetExportedTypes() ?? Enumerable.Empty()).Where(t => t.IsInterface && typeof(IHttpDeclarative).IsAssignableFrom(t)))); return this; } /// /// 添加 HTTP 声明式 提取器 /// /// 支持多次调用。 /// 实例提供器 /// /// /// public HttpRemoteBuilder AddHttpDeclarativeExtractors(Func> configure) { // 空检查 ArgumentNullException.ThrowIfNull(configure); _httpDeclarativeExtractors ??= new List>>(); _httpDeclarativeExtractors.Add(configure); return this; } /// /// 扫描程序集并添加 HTTP 声明式 提取器 /// /// 支持多次调用。 /// 集合 /// /// /// public HttpRemoteBuilder AddHttpDeclarativeExtractorFromAssemblies(params IEnumerable assemblies) { // 空检查 ArgumentNullException.ThrowIfNull(assemblies); return AddHttpDeclarativeExtractors(() => assemblies.SelectMany(ass => (ass?.GetExportedTypes() ?? Enumerable.Empty()).Where(t => t.HasDefinePublicParameterlessConstructor() && typeof(IHttpDeclarativeExtractor).IsAssignableFrom(t)) .Select(t => (IHttpDeclarativeExtractor)Activator.CreateInstance(t)!))); } /// /// 构建模块服务 /// /// /// /// internal void Build(IServiceCollection services) { // 注册 CodePagesEncodingProvider,使得程序能够识别并使用 Windows 代码页中的各种编码 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // 注册日志服务 services.AddLogging(); // 注册默认 HttpClient 客户端 if (services.All(u => u.ServiceType != typeof(IHttpClientFactory))) { services.AddHttpClient(); } // 检查是否配置(注册)了日志程序 var isLoggingRegistered = services.Any(u => u.ServiceType == typeof(ILoggerProvider)); // 注册并配置 HttpRemoteOptions 选项服务 services.Configure(options => { options.HttpDeclarativeExtractors = _httpDeclarativeExtractors?.AsReadOnly(); options.IsLoggingRegistered = isLoggingRegistered; }); // 注册 HttpContent 内容处理器工厂 services.TryAddSingleton(provider => new HttpContentProcessorFactory(provider, _httpContentProcessorProviders?.SelectMany(u => u.Invoke()).ToArray())); // 注册 HttpContent 内容转换器工厂 services.TryAddSingleton(provider => new HttpContentConverterFactory(provider, _httpContentConverterProviders?.SelectMany(u => u.Invoke()).ToArray())); // 注册对象内容转换器工厂 services.TryAddSingleton(); // 注册 HTTP 远程请求服务 services.TryAddSingleton(); // 检查是否自定义了对象内容转换器工厂,如果存在则替换 if (_objectContentConverterFactoryType is not null && _objectContentConverterFactoryType != typeof(ObjectContentConverterFactory)) { services.Replace(ServiceDescriptor.Singleton(typeof(IObjectContentConverterFactory), _objectContentConverterFactoryType)); } // 构建 HTTP 声明式远程请求服务 BuildHttpDeclarativeServices(services); } /// /// 构建 HTTP 声明式远程请求服务 /// /// /// /// internal void BuildHttpDeclarativeServices(IServiceCollection services) { // 空检查 if (_httpDeclarativeTypes is null) { return; } // 初始化 HTTP 声明式远程请求代理类类型 var httpDeclarativeDispatchProxyType = typeof(HttpDeclarativeDispatchProxy); // 遍历 HTTP 声明式远程请求类型并注册为服务 foreach (var httpDeclarativeType in _httpDeclarativeTypes) { services.TryAddSingleton(httpDeclarativeType, provider => { // 创建 HTTP 声明式远程请求代理实例 var httpDeclarative = DispatchProxyAsync.Create(httpDeclarativeType, httpDeclarativeDispatchProxyType) as HttpDeclarativeDispatchProxy; // 空检查 ArgumentNullException.ThrowIfNull(httpDeclarative); // 解析 IHttpRemoteService 服务并设置给 RemoteService 属性 httpDeclarative.RemoteService = provider.GetRequiredService(); return httpDeclarative; }); } } }