Skip to content

Commit

Permalink
Add new ExponentialRetryPolicy's default options to DI when missing
Browse files Browse the repository at this point in the history
  • Loading branch information
nozzlegear committed May 14, 2024
1 parent 99be0bc commit 5b19388
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using ShopifySharp.Utilities;
using System.Reflection;
using ShopifySharp.Infrastructure.Policies.ExponentialRetry;

namespace ShopifySharp.Extensions.DependencyInjection.Tests;

Expand Down Expand Up @@ -45,6 +46,33 @@ public void AddShopifySharpRequestExecutionPolicy_AllowsAddingMoreThanOnePolicy(
.BeOfType<TestRequestExecutionPolicy>();
}

[Fact]
public void AddShopifySharpRequestExecutionPolicy_WhenThePolicyIsExponentialRetry_AddsDefaultOptionsWhenTheyDontAlreadyExist()
{
// Setup
var container = new ServiceCollection();

// Act
container.AddShopifySharpRequestExecutionPolicy<ExponentialRetryPolicy>();

// Assert
var serviceProvider = container.BuildServiceProvider();
var options = serviceProvider.GetService<ExponentialRetryPolicyOptions>();
var policy = serviceProvider.GetService<IRequestExecutionPolicy>();

options.Should()
.NotBeNull()
.And
.BeOfType<ExponentialRetryPolicyOptions>()
.And
.BeEquivalentTo(ExponentialRetryPolicyOptions.Default());

policy.Should()
.NotBeNull()
.And
.BeOfType<ExponentialRetryPolicy>();
}

[Fact]
public void AddShopifySharpUtilities_AddsUtilities()
{
Expand Down Expand Up @@ -149,7 +177,7 @@ public void AddShopifySharpServiceFactories_AddsServiceFactories()
}

var serviceFactoryTypes = assembly
?.GetTypes()
.GetTypes()
.Where(t => t.IsInterface
&& t.IsPublic
&& t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IServiceFactory<>)))
Expand Down Expand Up @@ -197,6 +225,33 @@ public void AddShopifySharp_AddsRequestExecutionPolicy_AddsUtilities_ThenAddsSer
.BeOfType<OrderServiceFactory>();
}

[Fact]
public void AddShopifySharp_WhenThePolicyIsExponentialRetry_AddsDefaultOptionsWhenTheyDontAlreadyExist()
{
// Setup
var container = new ServiceCollection();

// Act
container.AddShopifySharp<ExponentialRetryPolicy>();

// Assert
var serviceProvider = container.BuildServiceProvider();
var options = serviceProvider.GetService<ExponentialRetryPolicyOptions>();
var policy = serviceProvider.GetService<IRequestExecutionPolicy>();

options.Should()
.NotBeNull()
.And
.BeOfType<ExponentialRetryPolicyOptions>()
.And
.BeEquivalentTo(ExponentialRetryPolicyOptions.Default());

policy.Should()
.NotBeNull()
.And
.BeOfType<ExponentialRetryPolicy>();
}

[Theory]
[InlineData(ServiceLifetime.Scoped)]
[InlineData(ServiceLifetime.Singleton)]
Expand Down Expand Up @@ -236,4 +291,4 @@ public void AddShopifySharp_AddsRequestExecutionPolicy_AddsUtilities_ThenAddsSer
.Should()
.NotBeNull(), serviceLifetime);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using ShopifySharp.Utilities;
using System.Reflection;
using System.Linq;
using ShopifySharp.Infrastructure.Policies.ExponentialRetry;

// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
Expand All @@ -25,6 +26,12 @@ public static class ServiceCollectionExtensions
public static IServiceCollection AddShopifySharpRequestExecutionPolicy<T>(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Singleton)
where T : class, IRequestExecutionPolicy
{
if (typeof(T) == typeof(ExponentialRetryPolicy))
{
services.AddImplementationIfNotRegistered<ExponentialRetryPolicyOptions, ExponentialRetryPolicyOptions>(
_ => ExponentialRetryPolicyOptions.Default(),
lifetime);
}
services.Add(new ServiceDescriptor(typeof(IRequestExecutionPolicy), typeof(T), lifetime));
return services;
}
Expand All @@ -43,7 +50,7 @@ public static IServiceCollection AddShopifySharpUtilities(this IServiceCollectio
{
var options = new ShopifySharpUtilityOptions();
configure?.Invoke(options);

if(options.OauthUtility != null)
{
services.Add(new ServiceDescriptor(typeof(IShopifyOauthUtility), f => options.OauthUtility, lifetime));
Expand Down Expand Up @@ -76,7 +83,7 @@ public static IServiceCollection AddShopifySharpUtilities(this IServiceCollectio

/// <summary>
/// Adds ShopifySharp's service factories to your Dependency Injection container. If you've added an <see cref="IRequestExecutionPolicy"/>,
/// the service factories will use it when creating ShopifySharp services.
/// the service factories will use it when creating ShopifySharp services.
/// </summary>
/// <param name="lifetime">The lifetime of ShopifySharp's service factories.</param>
public static IServiceCollection AddShopifySharpServiceFactories(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Singleton)
Expand Down Expand Up @@ -121,9 +128,29 @@ public static IServiceCollection AddShopifySharpServiceFactories(this IServiceCo
public static IServiceCollection AddShopifySharp<T>(this IServiceCollection services, ServiceLifetime lifetime = ServiceLifetime.Singleton)
where T : class, IRequestExecutionPolicy
{
if (typeof(T) == typeof(ExponentialRetryPolicy))
{
services.AddImplementationIfNotRegistered<ExponentialRetryPolicyOptions, ExponentialRetryPolicyOptions>(
_ => ExponentialRetryPolicyOptions.Default(),
lifetime);
}

return services
.AddShopifySharpRequestExecutionPolicy<T>(lifetime: lifetime)
.AddShopifySharpUtilities(lifetime: lifetime)
.AddShopifySharpServiceFactories(lifetime: lifetime);
}

/// <summary>
/// Registers the interface and its implementation if they aren't already registered.
/// </summary>
private static void AddImplementationIfNotRegistered<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> factory, ServiceLifetime lifetime)
where TImplementation : notnull, TService
{
services.TryAdd(new ServiceDescriptor(typeof(TService), (innerServices) =>
{
var output = factory.Invoke(innerServices);
return output;
}, lifetime));
}
}

0 comments on commit 5b19388

Please sign in to comment.