Skip to content

Commit

Permalink
Cosmos: Make it possible to configure a HttpClientFactory
Browse files Browse the repository at this point in the history
Fixes #21274
  • Loading branch information
dnperfors committed Aug 7, 2021
1 parent ccd7d07 commit dd21b40
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 2 deletions.
13 changes: 13 additions & 0 deletions src/EFCore.Cosmos/Infrastructure/CosmosDbContextOptionsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ public virtual CosmosDbContextOptionsBuilder Region(string region)
public virtual CosmosDbContextOptionsBuilder LimitToEndpoint(bool enable = true)
=> WithOption(e => e.WithLimitToEndpoint(Check.NotNull(enable, nameof(enable))));

/// <summary>
/// <para>
/// Configures the context to use a specific <see cref="HttpClient" /> factory.
/// </para>
/// <para>
/// To avoid multiple instances being created use <see langword="static" /> lambdas:
/// </para>
/// <code>.HttpClientFactory(static () => new HttpClient())</code>
/// </summary>
/// <param name="httpClientFactory">A function that returns an <see cref="HttpClient" />.</param>
public virtual CosmosDbContextOptionsBuilder HttpClientFactory(Func<HttpClient>? httpClientFactory)
=> WithOption(e => e.WithHttpClientFactory(Check.NotNull(httpClientFactory, nameof(httpClientFactory))));

/// <summary>
/// Configures the context to use the provided connection mode.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class CosmosOptionsExtension : IDbContextOptionsExtension
private int? _maxRequestsPerTcpConnection;
private bool? _enableContentResponseOnWrite;
private DbContextOptionsExtensionInfo? _info;
private Func<HttpClient>? _httpClientFactory;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down Expand Up @@ -74,6 +75,7 @@ protected CosmosOptionsExtension(CosmosOptionsExtension copyFrom)
_gatewayModeMaxConnectionLimit = copyFrom._gatewayModeMaxConnectionLimit;
_maxTcpConnectionsPerEndpoint = copyFrom._maxTcpConnectionsPerEndpoint;
_maxRequestsPerTcpConnection = copyFrom._maxRequestsPerTcpConnection;
_httpClientFactory = copyFrom._httpClientFactory;
}

/// <summary>
Expand Down Expand Up @@ -488,6 +490,29 @@ public virtual CosmosOptionsExtension ContentResponseOnWriteEnabled(bool enabled
return clone;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual Func<HttpClient>? HttpClientFactory => _httpClientFactory;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual CosmosOptionsExtension WithHttpClientFactory(Func<HttpClient>? httpClientFactory)
{
var clone = Clone();

clone._httpClientFactory = httpClientFactory;

return clone;
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand Down Expand Up @@ -559,6 +584,7 @@ public override int GetServiceProviderHashCode()
hashCode.Add(Extension._gatewayModeMaxConnectionLimit);
hashCode.Add(Extension._maxTcpConnectionsPerEndpoint);
hashCode.Add(Extension._maxRequestsPerTcpConnection);
hashCode.Add(Extension._httpClientFactory);

_serviceProviderHash = hashCode.ToHashCode();
}
Expand All @@ -581,7 +607,8 @@ public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo
&& Extension._idleTcpConnectionTimeout == otherInfo.Extension._idleTcpConnectionTimeout
&& Extension._gatewayModeMaxConnectionLimit == otherInfo.Extension._gatewayModeMaxConnectionLimit
&& Extension._maxTcpConnectionsPerEndpoint == otherInfo.Extension._maxTcpConnectionsPerEndpoint
&& Extension._maxRequestsPerTcpConnection == otherInfo.Extension._maxRequestsPerTcpConnection;
&& Extension._maxRequestsPerTcpConnection == otherInfo.Extension._maxRequestsPerTcpConnection
&& Extension._httpClientFactory == otherInfo.Extension._httpClientFactory;

public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@ public class CosmosSingletonOptions : ICosmosSingletonOptions
/// </summary>
public virtual bool? EnableContentResponseOnWrite { get; private set; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual Func<HttpClient>? HttpClientFactory { get; private set; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand All @@ -162,6 +170,7 @@ public virtual void Initialize(IDbContextOptions options)
GatewayModeMaxConnectionLimit = cosmosOptions.GatewayModeMaxConnectionLimit;
MaxTcpConnectionsPerEndpoint = cosmosOptions.MaxTcpConnectionsPerEndpoint;
MaxRequestsPerTcpConnection = cosmosOptions.MaxRequestsPerTcpConnection;
HttpClientFactory = cosmosOptions.HttpClientFactory;
}
}

Expand Down Expand Up @@ -190,6 +199,7 @@ public virtual void Validate(IDbContextOptions options)
|| MaxTcpConnectionsPerEndpoint != cosmosOptions.MaxTcpConnectionsPerEndpoint
|| MaxRequestsPerTcpConnection != cosmosOptions.MaxRequestsPerTcpConnection
|| EnableContentResponseOnWrite != cosmosOptions.EnableContentResponseOnWrite
|| HttpClientFactory != cosmosOptions.HttpClientFactory
))
{
throw new InvalidOperationException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,13 @@ public interface ICosmosSingletonOptions : ISingletonOptions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
bool? EnableContentResponseOnWrite { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
Func<HttpClient>? HttpClientFactory { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ public SingletonCosmosClientWrapper(ICosmosSingletonOptions options)
configuration.MaxRequestsPerTcpConnection = options.MaxRequestsPerTcpConnection.Value;
}

if (options.HttpClientFactory != null)
{
configuration.HttpClientFactory = options.HttpClientFactory;
}

_options = configuration;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ public void Can_create_options_with_valid_values()
Test(
o => o.IdleTcpConnectionTimeout(TimeSpan.FromMinutes(3)),
o => Assert.Equal(TimeSpan.FromMinutes(3), o.IdleTcpConnectionTimeout));
Func<HttpClient> httpClientFactory = () => new HttpClient();
Test(
o => o.HttpClientFactory(httpClientFactory),
o => Assert.Same(httpClientFactory, o.HttpClientFactory)
);
}

[ConditionalFact]
Expand Down Expand Up @@ -101,4 +106,3 @@ private void Throws<T>(Action<CosmosDbContextOptionsBuilder> cosmosOptionsAction
}
}
}

0 comments on commit dd21b40

Please sign in to comment.