Skip to content

Commit

Permalink
增加全局配置HttpApiOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
xljiulang committed Jun 10, 2021
1 parent 4fb100e commit be35ba6
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static void ConfigureHttpApiTest()
var name = HttpApi.GetName(typeof(IDiApi));
var options = services.GetService<IOptionsMonitor<HttpApiOptions>>().Get(name);
Assert.True(options.HttpHost == host);
}
}

[Fact]
public static void ConfigureHttpApiNoGenericTest()
Expand All @@ -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<IDiApi>();
di.ConfigureHttpApi<IDiApi>(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<IOptionsMonitor<HttpApiOptions>>().Get(name);
Assert.True(options.HttpHost == host);
Assert.True(options.UseParameterPropertyValidate == false);
Assert.True(options.UseReturnValuePropertyValidate == true);
}

public interface IDiApi
{
}
Expand Down
128 changes: 127 additions & 1 deletion WebApiClientCore/DependencyInjection/WebApiClientBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -24,6 +29,7 @@ public static IWebApiClientBuilder AddWebApiClient(this IServiceCollection servi
{
services.AddOptions();
services.AddMemoryCache();
services.TryAddTransient<IOptionsFactory<HttpApiOptions>, HttpApiOptionsFactory>();

services.TryAddSingleton(typeof(IHttpApiActivator<>), typeof(DefaultHttpApiActivator<>));
services.TryAddSingleton<IApiActionDescriptorProvider, DefaultApiActionDescriptorProvider>();
Expand All @@ -45,6 +51,42 @@ public static IWebApiClientBuilder UseJsonFirstApiActionDescriptor(this IWebApiC
return builder;
}

/// <summary>
/// 配置HttpApiOptions的默认值
/// </summary>
/// <param name="builder"></param>
/// <param name="configureOptions">配置选项</param>
/// <returns></returns>
public static IWebApiClientBuilder ConfigureHttpApi(this IWebApiClientBuilder builder, Action<HttpApiOptions, IServiceProvider> configureOptions)
{
builder.Services.AddOptions<HttpApiOptions>().Configure(configureOptions);
return builder;
}

/// <summary>
/// 配置HttpApiOptions的默认值
/// </summary>
/// <param name="builder"></param>
/// <param name="configureOptions">配置选项</param>
/// <returns></returns>
public static IWebApiClientBuilder ConfigureHttpApi(this IWebApiClientBuilder builder, Action<HttpApiOptions> configureOptions)
{
builder.Services.AddOptions<HttpApiOptions>().Configure(configureOptions);
return builder;
}

/// <summary>
/// 配置HttpApiOptions的默认值
/// </summary>
/// <param name="builder"></param>
/// <param name="configuration">配置</param>
/// <returns></returns>
public static IWebApiClientBuilder ConfigureHttpApi(this IWebApiClientBuilder builder, IConfiguration configuration)
{
builder.Services.AddOptions<HttpApiOptions>().Bind(configuration);
return builder;
}

/// <summary>
/// WebApiClient全局配置的Builder
/// </summary>
Expand All @@ -60,5 +102,89 @@ public WebApiClientBuilder(IServiceCollection services)
this.Services = services;
}
}

/// <summary>
/// HttpApiOptions工厂
/// </summary>
private class HttpApiOptionsFactory : IOptionsFactory<HttpApiOptions>
{
private readonly IConfigureOptions<HttpApiOptions>[] _setups;
private readonly IPostConfigureOptions<HttpApiOptions>[] _postConfigures;
private readonly IValidateOptions<HttpApiOptions>[] _validations;

/// <summary>
/// HttpApiOptions工厂
/// </summary>
/// <param name="setups"></param>
/// <param name="postConfigures"></param>
/// <param name="validations"></param>
public HttpApiOptionsFactory(IEnumerable<IConfigureOptions<HttpApiOptions>> setups, IEnumerable<IPostConfigureOptions<HttpApiOptions>> postConfigures, IEnumerable<IValidateOptions<HttpApiOptions>> validations)
{
_setups = setups as IConfigureOptions<HttpApiOptions>[] ?? setups.ToArray();
_postConfigures = postConfigures as IPostConfigureOptions<HttpApiOptions>[] ?? postConfigures.ToArray();
_validations = validations as IValidateOptions<HttpApiOptions>[] ?? validations.ToArray();
}

/// <summary>
/// 创建Options
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public HttpApiOptions Create(string name)
{
var defaultOptions = this.Create(Options.Options.DefaultName, default);
return this.Create(name, defaultOptions);
}

/// <summary>
/// 创建Options
/// </summary>
/// <param name="name"></param>
/// <param name="options">传入的实例</param>
/// <returns></returns>
private HttpApiOptions Create(string name, HttpApiOptions? options)
{
if (options == null)
{
options = new HttpApiOptions();
}

foreach (var setup in _setups)
{
if (setup is IConfigureNamedOptions<HttpApiOptions> 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<string>();
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;
}
}
}
}

0 comments on commit be35ba6

Please sign in to comment.