diff --git a/WebApiClientCore.Test/Microsoft.Extensions/DependencyInjection/DependencyInjectionTest.cs b/WebApiClientCore.Test/Microsoft.Extensions/DependencyInjection/DependencyInjectionTest.cs index e59366bf..20e52d65 100644 --- a/WebApiClientCore.Test/Microsoft.Extensions/DependencyInjection/DependencyInjectionTest.cs +++ b/WebApiClientCore.Test/Microsoft.Extensions/DependencyInjection/DependencyInjectionTest.cs @@ -41,7 +41,7 @@ public static void ConfigureHttpApiTest() var name = HttpApi.GetName(typeof(IDiApi)); var options = services.GetService>().Get(name); Assert.True(options.HttpHost == host); - } + } [Fact] public static void ConfigureHttpApiNoGenericTest() @@ -60,6 +60,32 @@ public static void ConfigureHttpApiNoGenericTest() } + [Fact] + public static void ConfigureHttpApiWithDefaultTest() + { + var di = new ServiceCollection(); + var host = new Uri("http://www.x.com"); + di.AddHttpApi(); + di.ConfigureHttpApi(o => + { + o.HttpHost = host; + Assert.True(o.UseParameterPropertyValidate == false); + Assert.True(o.UseReturnValuePropertyValidate == true); + }); + di.AddWebApiClient().ConfigureHttpApi(o => + { + o.UseParameterPropertyValidate = false; + o.UseReturnValuePropertyValidate = true; + }); + var services = di.BuildServiceProvider(); + + var name = HttpApi.GetName(typeof(IDiApi)); + var options = services.GetService>().Get(name); + Assert.True(options.HttpHost == host); + Assert.True(options.UseParameterPropertyValidate == false); + Assert.True(options.UseReturnValuePropertyValidate == true); + } + public interface IDiApi { } diff --git a/WebApiClientCore/DependencyInjection/WebApiClientBuilderExtensions.cs b/WebApiClientCore/DependencyInjection/WebApiClientBuilderExtensions.cs index a22f7291..3e6503e8 100644 --- a/WebApiClientCore/DependencyInjection/WebApiClientBuilderExtensions.cs +++ b/WebApiClientCore/DependencyInjection/WebApiClientBuilderExtensions.cs @@ -1,4 +1,9 @@ -using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection.Extensions; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; using WebApiClientCore; using WebApiClientCore.Implementations; @@ -24,6 +29,7 @@ public static IWebApiClientBuilder AddWebApiClient(this IServiceCollection servi { services.AddOptions(); services.AddMemoryCache(); + services.TryAddTransient, HttpApiOptionsFactory>(); services.TryAddSingleton(typeof(IHttpApiActivator<>), typeof(DefaultHttpApiActivator<>)); services.TryAddSingleton(); @@ -45,6 +51,42 @@ public static IWebApiClientBuilder UseJsonFirstApiActionDescriptor(this IWebApiC return builder; } + /// + /// 配置HttpApiOptions的默认值 + /// + /// + /// 配置选项 + /// + public static IWebApiClientBuilder ConfigureHttpApi(this IWebApiClientBuilder builder, Action configureOptions) + { + builder.Services.AddOptions().Configure(configureOptions); + return builder; + } + + /// + /// 配置HttpApiOptions的默认值 + /// + /// + /// 配置选项 + /// + public static IWebApiClientBuilder ConfigureHttpApi(this IWebApiClientBuilder builder, Action configureOptions) + { + builder.Services.AddOptions().Configure(configureOptions); + return builder; + } + + /// + /// 配置HttpApiOptions的默认值 + /// + /// + /// 配置 + /// + public static IWebApiClientBuilder ConfigureHttpApi(this IWebApiClientBuilder builder, IConfiguration configuration) + { + builder.Services.AddOptions().Bind(configuration); + return builder; + } + /// /// WebApiClient全局配置的Builder /// @@ -60,5 +102,89 @@ public WebApiClientBuilder(IServiceCollection services) this.Services = services; } } + + /// + /// HttpApiOptions工厂 + /// + private class HttpApiOptionsFactory : IOptionsFactory + { + private readonly IConfigureOptions[] _setups; + private readonly IPostConfigureOptions[] _postConfigures; + private readonly IValidateOptions[] _validations; + + /// + /// HttpApiOptions工厂 + /// + /// + /// + /// + public HttpApiOptionsFactory(IEnumerable> setups, IEnumerable> postConfigures, IEnumerable> validations) + { + _setups = setups as IConfigureOptions[] ?? setups.ToArray(); + _postConfigures = postConfigures as IPostConfigureOptions[] ?? postConfigures.ToArray(); + _validations = validations as IValidateOptions[] ?? validations.ToArray(); + } + + /// + /// 创建Options + /// + /// + /// + public HttpApiOptions Create(string name) + { + var defaultOptions = this.Create(Options.Options.DefaultName, default); + return this.Create(name, defaultOptions); + } + + /// + /// 创建Options + /// + /// + /// 传入的实例 + /// + private HttpApiOptions Create(string name, HttpApiOptions? options) + { + if (options == null) + { + options = new HttpApiOptions(); + } + + foreach (var setup in _setups) + { + if (setup is IConfigureNamedOptions namedSetup) + { + namedSetup.Configure(name, options); + } + else if (name == Options.Options.DefaultName) + { + setup.Configure(options); + } + } + + foreach (var post in _postConfigures) + { + post.PostConfigure(name, options); + } + + if (_validations != null) + { + var failures = new List(); + foreach (var validate in _validations) + { + var result = validate.Validate(name, options); + if (result != null && result.Failed) + { + failures.AddRange(result.Failures); + } + } + if (failures.Count > 0) + { + throw new OptionsValidationException(name, typeof(HttpApiOptions), failures); + } + } + + return options; + } + } } }