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 41dd6ef commit dae78ef
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 51 deletions.
45 changes: 39 additions & 6 deletions ShipEngine/ShipEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,33 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace ShipEngineSDK
{
public static class ShipEngineExtensions
{
public static IHostApplicationBuilder AddShipEngine(this IHostApplicationBuilder builder, Action<HttpClient>? clientOverride = null)
{
builder.Services.AddHttpClient<ShipEngine>(c =>
{
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
62 changes: 32 additions & 30 deletions ShipEngine/ShipEngine.csproj
Original file line number Diff line number Diff line change
@@ -1,39 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<PackageId>ShipEngine</PackageId>
<PackageTags>sdk;rest;api;shipping;rates;label;tracking;cost;address;validation;normalization;fedex;ups;usps;</PackageTags>
<PropertyGroup>
<PackageId>ShipEngine</PackageId>
<PackageTags>sdk;rest;api;shipping;rates;label;tracking;cost;address;validation;normalization;fedex;ups;usps;</PackageTags>

<Version>2.0.0</Version>
<Authors>ShipEngine</Authors>
<Company>ShipEngine</Company>
<Summary>The official ShipEngine C# SDK for .NET</Summary>
<Description>The official ShipEngine C# SDK for .NET</Description>
<PackageIcon>icon.png</PackageIcon>
<Version>2.0.0</Version>
<Authors>ShipEngine</Authors>
<Company>ShipEngine</Company>
<Summary>The official ShipEngine C# SDK for .NET</Summary>
<Description>The official ShipEngine C# SDK for .NET</Description>
<PackageIcon>icon.png</PackageIcon>

<PackageProjectUrl>https://github.com/ShipEngine/shipengine-dotnet</PackageProjectUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageProjectUrl>https://github.com/ShipEngine/shipengine-dotnet</PackageProjectUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Macross.Json.Extensions" Version="3.0.0" />
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Macross.Json.Extensions" Version="3.0.0" />
<PackageReference Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />
</ItemGroup>

<ItemGroup>
<None Include="icon.png" Pack="true" PackagePath="\" />
<None Include="../LICENSE" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<None Include="icon.png" Pack="true" PackagePath="\" />
<None Include="../LICENSE" Pack="true" PackagePath="" />
</ItemGroup>

</Project>
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 dae78ef

Please sign in to comment.