Skip to content

Commit

Permalink
feat: add method to initialize SDK with an httpClient
Browse files Browse the repository at this point in the history
  • Loading branch information
jpill committed Jun 10, 2024
1 parent 15dfaf5 commit ed17c45
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 23 deletions.
47 changes: 40 additions & 7 deletions ShipEngine/ShipEngine.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,34 @@
using ShipEngineSDK.Common;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using ShipEngineSDK.Common;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace ShipEngineSDK
{
public static class ShipEngineExtensions
{
public static IHostApplicationBuilder AddShipEngine(this IHostApplicationBuilder builder, Action<HttpClient>? clientOverride = null)
{
builder.Services.AddHttpClient<ShipEngine>(c =>

Check failure on line 16 in ShipEngine/ShipEngine.cs

View workflow job for this annotation

GitHub Actions / .Net 8.0 on ubuntu-latest

'IServiceCollection' does not contain a definition for 'AddHttpClient' and no accessible extension method 'AddHttpClient' accepting a first argument of type 'IServiceCollection' could be found (are you missing a using directive or an assembly reference?)

Check failure on line 16 in ShipEngine/ShipEngine.cs

View workflow job for this annotation

GitHub Actions / .Net 8.0 on ubuntu-latest

'IServiceCollection' does not contain a definition for 'AddHttpClient' and no accessible extension method 'AddHttpClient' accepting a first argument of type 'IServiceCollection' could be found (are you missing a using directive or an assembly reference?)
{
var baseUri = builder.Configuration["ShipEngine:BaseUrl"] ?? "https://api.shipengine.com";
var apiKey = builder.Configuration["ShipEngine:ApiKey"];
ShipEngineClient.ConfigureHttpClient(c, apiKey, new Uri(baseUri));
clientOverride?.Invoke(c);
});

return builder;
}
}

/// <summary>
/// Contains methods for interacting with the ShipEngine API.
/// </summary>
public class ShipEngine : ShipEngineClient
public class ShipEngine : ShipEngineClient, IDisposable
{
/// <summary>
/// Global HttpClient for ShipEngine instance.
Expand All @@ -28,9 +46,8 @@ public class ShipEngine : ShipEngineClient
/// <param name="apiKey">Api Key associated with the ShipEngine account you want to use</param>
public ShipEngine(string apiKey) : base()
{
var client = new HttpClient();
_config = new Config(apiKey);
_client = ConfigureHttpClient(_config, client);
_client = ConfigureHttpClient(_config, new HttpClient());
}

/// <summary>
Expand All @@ -39,9 +56,25 @@ public ShipEngine(string apiKey) : base()
/// <param name="config">Config object containing custom configurations</param>
public ShipEngine(Config config) : base()
{
var client = new HttpClient();
this._config = config;
_client = ConfigureHttpClient(config, client);
_client = ConfigureHttpClient(config, new HttpClient());
}

/// <summary>
/// Initialize the ShipEngine SDK with an httpClient object
/// </summary>
/// <param name="httpClient">HttpClient object to be used for ShipEngine API calls. We expect the httpClient has already been configured with ConfigureHttpClient</param>
public ShipEngine(HttpClient httpClient) : base()
{
_client = httpClient;
}

// <summary>
// Dispose of the ShipEngine client
// </summary>
public void Dispose()
{
_client.Dispose();
}

/// <summary>
Expand Down
4 changes: 3 additions & 1 deletion ShipEngine/ShipEngine.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />
<None Include="..\README.md" Pack="true" PackagePath="\"/>
<None Include="..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
Expand Down
46 changes: 31 additions & 15 deletions ShipEngine/ShipEngineClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,14 @@ public class ShipEngineClient
/// Options for serializing the method call params to JSON.
/// A separate inline setting is used for deserializing the response
/// </summary>
protected readonly JsonSerializerOptions JsonSerializerOptions;

/// <summary>
/// Constructor for ShipEngineClient
/// </summary>
public ShipEngineClient()
protected static readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions
{
JsonSerializerOptions = new JsonSerializerOptions
{
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
PropertyNameCaseInsensitive = true,
WriteIndented = true,
Converters = { new JsonStringEnumMemberConverter() }
};
}
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
PropertyNameCaseInsensitive = true,
WriteIndented = true,
Converters = { new JsonStringEnumMemberConverter() }
};

private const string JsonMediaType = "application/json";

Expand Down Expand Up @@ -71,6 +63,30 @@ public static HttpClient ConfigureHttpClient(Config config, HttpClient client)
return client;
}

public static HttpClient ConfigureHttpClient(HttpClient client, string apiKey, Uri? baseUri, TimeSpan? timeout = null)
{
client.DefaultRequestHeaders.Accept.Clear();

var osPlatform = Environment.OSVersion.Platform.ToString();
var osVersion = Environment.OSVersion.Version.ToString();
var clrVersion = Environment.Version.ToString();

var sdkVersionObject = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
var sdkVersion = $"{sdkVersionObject.Major}.{sdkVersionObject.Minor}.{sdkVersionObject.Build}";

var userAgentString = $"shipengine-dotnet/{sdkVersion} {osPlatform}/{osVersion} clr/{clrVersion}";

client.DefaultRequestHeaders.Add("User-Agent", userAgentString);
client.DefaultRequestHeaders.Add("Api-Key", apiKey);
client.DefaultRequestHeaders.Add("Accept", JsonMediaType);

client.BaseAddress = baseUri ?? new Uri("https://api.shipengine.com");

client.Timeout = timeout ?? TimeSpan.FromSeconds(60);

return client;
}

private async Task<T> DeserializedResultOrThrow<T>(HttpResponseMessage response)
{

Expand Down

0 comments on commit ed17c45

Please sign in to comment.