From 91e6a20ec777ae08bd529ec523989eda8eb9af40 Mon Sep 17 00:00:00 2001 From: Eoin O'Connor Date: Sun, 6 Mar 2016 12:54:01 +1100 Subject: [PATCH] [https://github.com/eoin55/HoneyBear.HalClient/issues/3] - Added two constructor overloads of HalClient, so that IJsonHttpClient can be passed in. This should allow developers to provide their own implementation of IJsonHttpClient rather than use the default one. --- README.md | 54 +++++++++++++++++-- Src/HoneyBear.HalClient/HalClient.cs | 25 ++++++++- .../Http/IJsonHttpClient.cs | 38 ++++++++++++- .../Http/JsonHttpClient.cs | 2 +- 4 files changed, 109 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 866fe1f..a3a4a2f 100644 --- a/README.md +++ b/README.md @@ -41,16 +41,16 @@ Install-Package HoneyBear.HalClient ### 2) Create an instance of HalClient `HalClient` has a dependency on `HttpClient`. This can be provided in the constructor: ```cs -var client = new HalClient(new HttpClient { BaseAddress = new Uri("https://api.retail.com/") }); +var halClent = new HalClient(new HttpClient { BaseAddress = new Uri("https://api.retail.com/") }); ``` Or accessed via a public property: ```cs -var client = new HalClient(); -client.HttpClient.BaseAddress = new Uri("https://api.retail.com/"); +var halClent = new HalClient(); +halClent.HttpClient.BaseAddress = new Uri("https://api.retail.com/"); ``` #### (Optional) Custom serializer settings -HalClient uses the default JsonMediaTypeFormatter for handling serialization and deserialization. If you need to change any of the settings (for handling null values, missing properties, custom date formats and so on), you can build a custom MediaTypeFormatter by subclassing JsonMediaTypeFormatter, and then passing it in to the HalClient constructor: +HalClient uses the default JsonMediaTypeFormatter for handling deserialization of responses. If you need to change any of the settings (for handling null values, missing properties, custom date formats and so on), you can build a custom MediaTypeFormatter by subclassing JsonMediaTypeFormatter, and then passing it in to the HalClient constructor: ```cs public class CustomMediaTypeFormatter : JsonMediaTypeFormatter { @@ -59,7 +59,51 @@ public class CustomMediaTypeFormatter : JsonMediaTypeFormatter SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/hal+json")); } -var client = new HalClient(new HttpClient { BaseAddress = new Uri("https://api.retail.com/") }, new List { new CustomMediaTypeFormatter() }); +var halClent = new HalClient(new HttpClient { BaseAddress = new Uri("https://api.retail.com/") }, new List { new CustomMediaTypeFormatter() }); +``` + +### (Optional) Override default implementation of IJsonHttpClient +By default, `HalClient` uses a internal implementation of `IJsonHttpClient`, which uses `HttpClient` to perform HTTP requests (GET, POST, PUT and DELETE). In some cases, it may be preferable to provide your own implementation of `IJsonHttpClient`. For example, if you want to specify a different `MediaTypeFormatter` for serializing POST and PUT requests: + +```cs +public class CustomJsonHttpClient : IJsonHttpClient +{ + private readonly CustomMediaTypeFormatter _formatter; + + public CustomJsonHttpClient(HttpClient client, CustomMediaTypeFormatter formatter) + { + HttpClient = client; + _formatter = formatter; + HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/hal+json")); + } + + public HttpClient HttpClient { get; } + + public Task GetAsync(string uri) + => HttpClient.GetAsync(uri); + + public Task PostAsync(string uri, T value) + => HttpClient.PostAsync(uri, value, _formatter); + + public Task PutAsync(string uri, T value) + => HttpClient.PutAsync(uri, value, _formatter); + + public Task DeleteAsync(string uri) + => HttpClient.DeleteAsync(uri); +} +``` + +```cs +var jsonClient = new CustomJsonHttpClient(new HttpClient(), new CustomMediaTypeFormatter()); +var halClent = new HalClient(jsonClient); +``` + +or + +```cs +var jsonClient = new CustomJsonHttpClient(new HttpClient(), new CustomMediaTypeFormatter()); +var formatters = new List { new CustomMediaTypeFormatter() }; +var halClent = new HalClient(jsonClient, formatters); ``` ## Usage Examples diff --git a/Src/HoneyBear.HalClient/HalClient.cs b/Src/HoneyBear.HalClient/HalClient.cs index 628c57e..db33845 100644 --- a/Src/HoneyBear.HalClient/HalClient.cs +++ b/Src/HoneyBear.HalClient/HalClient.cs @@ -59,10 +59,31 @@ public HalClient() } - internal HalClient(IJsonHttpClient client) + /// + /// Creates an instance of the class. + /// + /// The implementation of to use. + /// + /// Specifies the list of s to use. + /// Default is . + /// + public HalClient( + IJsonHttpClient client, + ICollection formatters) { _client = client; - _formatters = _defaultFormatters; + _formatters = formatters == null || !formatters.Any() ? _defaultFormatters : formatters; + } + + /// + /// Creates an instance of the class. + /// + /// The implementation of to use. + public HalClient( + IJsonHttpClient client) + : this(client, _defaultFormatters) + { + } /// diff --git a/Src/HoneyBear.HalClient/Http/IJsonHttpClient.cs b/Src/HoneyBear.HalClient/Http/IJsonHttpClient.cs index f95eab2..94966e4 100644 --- a/Src/HoneyBear.HalClient/Http/IJsonHttpClient.cs +++ b/Src/HoneyBear.HalClient/Http/IJsonHttpClient.cs @@ -3,12 +3,46 @@ namespace HoneyBear.HalClient.Http { - internal interface IJsonHttpClient + /// + /// Provides a wrapper for that processes JSON HTTP requests and responses. + /// + public interface IJsonHttpClient { + /// + /// A getter for the wrapped instance of . + /// HttpClient HttpClient { get; } + + /// + /// Send a GET request to the specified Uri as an asynchronous operation. + /// + /// The Uri the request is sent to. + /// Returns .The task object representing the asynchronous operation. Task GetAsync(string uri); + + /// + /// Send a POST request to the specified Uri as an asynchronous operation. + /// + /// + /// The Uri the request is sent to. + /// The HTTP request content sent to the server. + /// Returns .The task object representing the asynchronous operation. Task PostAsync(string uri, T value); + + /// + /// Send a PUT request to the specified Uri as an asynchronous operation. + /// + /// + /// The Uri the request is sent to. + /// The HTTP request content sent to the server. + /// Returns .The task object representing the asynchronous operation. Task PutAsync(string uri, T value); + + /// + /// Send a DELETE request to the specified Uri as an asynchronous operation. + /// + /// The Uri the request is sent to. + /// Returns .The task object representing the asynchronous operation. Task DeleteAsync(string uri); } -} \ No newline at end of file +} diff --git a/Src/HoneyBear.HalClient/Http/JsonHttpClient.cs b/Src/HoneyBear.HalClient/Http/JsonHttpClient.cs index fd6b0a0..b58afcd 100644 --- a/Src/HoneyBear.HalClient/Http/JsonHttpClient.cs +++ b/Src/HoneyBear.HalClient/Http/JsonHttpClient.cs @@ -4,7 +4,7 @@ namespace HoneyBear.HalClient.Http { - internal class JsonHttpClient : IJsonHttpClient + internal sealed class JsonHttpClient : IJsonHttpClient { public JsonHttpClient(HttpClient client) {