diff --git a/CHANGELOG.md b/CHANGELOG.md index e49f22c..a425627 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,16 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org/) for commit guidelines. -## [2.0.0](https://github.com/JustinCanton/Geo.NET/compare/1.6.0...2.0.0) (2024-01-20) +## [2.0.0](https://github.com/JustinCanton/Geo.NET/compare/1.6.0...2.0.0) (2024-01-30) ### ⚠ BREAKING CHANGES - removed native support for net5.0 since it is an out of support item, and dropped netstandard2.1 since this supports netstandard2.0 -- removed the usage of Newtonsoft.Json and now uses on System.Text.Json +- removed the usage of Newtonsoft.Json and moved to use System.Text.Json +- changed the exceptions returned from all services to GeoNETException instead of individual exceptions per API, as well as removed some now-deprecated interface types and implementations ### Features - **runtime**: updating the .net version support for net8.0, and removing native support for netstandard2.1 and net5.0 ([#58](https://github.com/JustinCanton/Geo.NET/issues/58)) ([4398a10](https://github.com/JustinCanton/Geo.NET/commit/4398a10afb21d3e7e86fba0fa4052adb67ca1faa)) -- **serialization**: updating to use System.Text.Json instead of Newtonsoft.Json ([#40](https://github.com/JustinCanton/Geo.NET/issues/40)) ([4398a10](https://github.com/JustinCanton/Geo.NET/commit/4398a10afb21d3e7e86fba0fa4052adb67ca1faa)) +- **serialization**: updating to use System.Text.Json instead of Newtonsoft.Json ([#40](https://github.com/JustinCanton/Geo.NET/issues/40)) ([e108ec6](https://github.com/JustinCanton/Geo.NET/commit/e108ec65d895d8d7fa792845973f14cdcc7335ae)) +- **exceptions**: updating how exceptions are handled and removing unused interfaces ([#95](https://github.com/JustinCanton/Geo.NET/issues/95)) ([e108ec6](https://github.com/JustinCanton/Geo.NET/commit/e108ec65d895d8d7fa792845973f14cdcc7335ae)) ## [1.6.0](https://github.com/JustinCanton/Geo.NET/compare/1.5.2...1.6.0) (2023-12-29) ### Features diff --git a/src/Geo.ArcGIS/Abstractions/IArcGISGeocoding.cs b/src/Geo.ArcGIS/Abstractions/IArcGISGeocoding.cs index b05218f..a2d6a4e 100644 --- a/src/Geo.ArcGIS/Abstractions/IArcGISGeocoding.cs +++ b/src/Geo.ArcGIS/Abstractions/IArcGISGeocoding.cs @@ -7,9 +7,9 @@ namespace Geo.ArcGIS.Abstractions { using System.Threading; using System.Threading.Tasks; - using Geo.ArcGIS.Models.Exceptions; using Geo.ArcGIS.Models.Parameters; using Geo.ArcGIS.Models.Responses; + using Geo.Core.Models.Exceptions; /// /// An interface for calling the ArcGIS geocoding API. @@ -22,7 +22,7 @@ public interface IArcGISGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from ArcGIS. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task AddressCandidateAsync(AddressCandidateParameters parameters, CancellationToken cancellationToken = default); /// @@ -31,7 +31,7 @@ public interface IArcGISGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from ArcGIS. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task PlaceCandidateAsync(PlaceCandidateParameters parameters, CancellationToken cancellationToken = default); /// @@ -40,7 +40,7 @@ public interface IArcGISGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from ArcGIS. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task SuggestAsync(SuggestParameters parameters, CancellationToken cancellationToken = default); /// @@ -49,7 +49,7 @@ public interface IArcGISGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from ArcGIS. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task ReverseGeocodingAsync(ReverseGeocodingParameters parameters, CancellationToken cancellationToken = default); /// @@ -58,7 +58,7 @@ public interface IArcGISGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from ArcGIS. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task GeocodingAsync(GeocodingParameters parameters, CancellationToken cancellationToken = default); } } diff --git a/src/Geo.ArcGIS/DependencyInjection/ServiceCollectionExtensions.cs b/src/Geo.ArcGIS/DependencyInjection/ServiceCollectionExtensions.cs index e86bb18..5a7e47c 100644 --- a/src/Geo.ArcGIS/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Geo.ArcGIS/DependencyInjection/ServiceCollectionExtensions.cs @@ -10,7 +10,6 @@ namespace Geo.ArcGIS.DependencyInjection using Geo.ArcGIS.Abstractions; using Geo.ArcGIS.Models; using Geo.ArcGIS.Services; - using Geo.Core.DependencyInjection; using Microsoft.Extensions.DependencyInjection; /// @@ -37,8 +36,6 @@ public static IHttpClientBuilder AddArcGISServices( Action optionsBuilder, Action configureClient = null) { - services.AddCoreServices(); - if (optionsBuilder != null) { var options = new ArcGISOptionsBuilder(); diff --git a/src/Geo.ArcGIS/Geo.ArcGIS.csproj b/src/Geo.ArcGIS/Geo.ArcGIS.csproj index 76edc2f..399c723 100644 --- a/src/Geo.ArcGIS/Geo.ArcGIS.csproj +++ b/src/Geo.ArcGIS/Geo.ArcGIS.csproj @@ -10,6 +10,7 @@ MIT https://github.com/JustinCanton/Geo.NET true + README.md @@ -33,4 +34,11 @@ + + + True + \ + + + diff --git a/src/Geo.ArcGIS/Models/Exceptions/ArcGISException.cs b/src/Geo.ArcGIS/Models/Exceptions/ArcGISException.cs deleted file mode 100644 index 1916b8e..0000000 --- a/src/Geo.ArcGIS/Models/Exceptions/ArcGISException.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.ArcGIS.Models.Exceptions -{ - using System; - using System.Globalization; - using System.Net.Http; - using System.Text.Json; - using System.Threading.Tasks; - using Geo.Core.Models.Exceptions; - - /// - /// A wrapper exception for any exceptions thrown in the ArcGIS functionality. The current exceptions wrapped by this exception are listed. - /// - /// Thrown when the parameter object is null or the request uri is null. - /// Thrown when the required parameter for the Google request is null or invalid. - /// - /// Thrown when the request failed due to an underlying issue such as network connectivity, - /// DNS failure, server certificate validation or timeout. - /// - /// Thrown when the ArcGIS request is cancelled. - /// Thrown when when an error occurs during JSON deserialization. - public sealed class ArcGISException : GeoCoreException - { - private const string DefaultMessage = "{0} See the inner exception for more information."; - - /// - /// Initializes a new instance of the class. - /// - public ArcGISException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public ArcGISException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - /// The exception that is the cause of the current exception. - public ArcGISException(string message, Exception inner) - : base(string.Format(CultureInfo.InvariantCulture, DefaultMessage, message), inner) - { - } - } -} diff --git a/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs b/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs index a23fbe6..35b99b1 100644 --- a/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs +++ b/src/Geo.ArcGIS/Services/ArcGISGeocoding.cs @@ -16,27 +16,25 @@ namespace Geo.ArcGIS.Services using System.Threading.Tasks; using Geo.ArcGIS.Abstractions; using Geo.ArcGIS.Enums; - using Geo.ArcGIS.Models.Exceptions; using Geo.ArcGIS.Models.Parameters; using Geo.ArcGIS.Models.Responses; using Geo.Core; using Geo.Core.Extensions; + using Geo.Core.Models.Exceptions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; /// /// A service to call the ArcGIS geocoding API. /// - public class ArcGISGeocoding : ClientExecutor, IArcGISGeocoding + public class ArcGISGeocoding : GeoClient, IArcGISGeocoding { - private const string ApiName = "ArcGIS"; private const string CandidatesUri = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/findAddressCandidates"; private const string SuggestUri = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/suggest"; private const string ReverseGeocodingUri = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode"; private const string GeocodingUri = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/geocodeAddresses"; private readonly IArcGISTokenContainer _tokenContainer; - private readonly IGeoNETResourceStringProvider _resourceStringProvider; private readonly ILogger _logger; /// @@ -44,22 +42,20 @@ public class ArcGISGeocoding : ClientExecutor, IArcGISGeocoding /// /// A used for making calls to the ArcGIS system. /// An used for retreiving the ArcGIS token. - /// An used to provide exceptions based on an exception type. - /// An used to create a resource string provider for log or exception messages. /// An used to create a logger used for logging information. public ArcGISGeocoding( HttpClient client, IArcGISTokenContainer tokenContainer, - IGeoNETExceptionProvider exceptionProvider, - IGeoNETResourceStringProviderFactory resourceStringProviderFactory, ILoggerFactory loggerFactory = null) - : base(client, exceptionProvider, resourceStringProviderFactory, loggerFactory) + : base(client, loggerFactory) { _tokenContainer = tokenContainer ?? throw new ArgumentNullException(nameof(tokenContainer)); - _resourceStringProvider = resourceStringProviderFactory?.CreateResourceStringProvider() ?? throw new ArgumentNullException(nameof(resourceStringProviderFactory)); _logger = loggerFactory?.CreateLogger() ?? NullLogger.Instance; } + /// + protected override string ApiName => "ArcGIS"; + /// public async Task AddressCandidateAsync( AddressCandidateParameters parameters, @@ -67,7 +63,7 @@ public async Task AddressCandidateAsync( { var uri = await ValidateAndBuildUri(parameters, BuildAddressCandidateRequest, cancellationToken).ConfigureAwait(false); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -77,7 +73,7 @@ public async Task PlaceCandidateAsync( { var uri = await ValidateAndBuildUri(parameters, BuildPlaceCandidateRequest, cancellationToken).ConfigureAwait(false); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -87,7 +83,7 @@ public async Task SuggestAsync( { var uri = await ValidateAndBuildUri(parameters, BuildSuggestRequest, cancellationToken).ConfigureAwait(false); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -97,7 +93,7 @@ public async Task ReverseGeocodingAsync( { var uri = await ValidateAndBuildUri(parameters, BuildReverseGeocodingRequest, cancellationToken).ConfigureAwait(false); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -107,7 +103,7 @@ public async Task GeocodingAsync( { var uri = await ValidateAndBuildUri(parameters, BuildGeocodingRequest, cancellationToken).ConfigureAwait(false); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -138,9 +134,8 @@ internal async Task ValidateAndBuildUri( { if (parameters is null) { - var error = _resourceStringProvider.GetString("Null Parameters"); - _logger.ArcGISError(error); - throw new ArcGISException(error, new ArgumentNullException(nameof(parameters))); + _logger.ArcGISError(Resources.Services.ArcGISGeocoding.Null_Parameters); + throw new GeoNETException(Resources.Services.ArcGISGeocoding.Null_Parameters, new ArgumentNullException(nameof(parameters))); } try @@ -149,9 +144,8 @@ internal async Task ValidateAndBuildUri( } catch (ArgumentException ex) { - var error = _resourceStringProvider.GetString("Failed To Create Uri"); - _logger.ArcGISError(error); - throw new ArcGISException(error, ex); + _logger.ArcGISError(Resources.Services.ArcGISGeocoding.Failed_To_Create_Uri); + throw new GeoNETException(Resources.Services.ArcGISGeocoding.Failed_To_Create_Uri, ex); } } @@ -165,9 +159,8 @@ internal async Task BuildAddressCandidateRequest(AddressCandidateParameters { if (string.IsNullOrWhiteSpace(parameters.SingleLineAddress)) { - var error = _resourceStringProvider.GetString("Invalid Single Address Line"); - _logger.ArcGISError(error); - throw new ArgumentException(error, nameof(parameters.SingleLineAddress)); + _logger.ArcGISError(Resources.Services.ArcGISGeocoding.Invalid_Single_Address_Line); + throw new ArgumentException(Resources.Services.ArcGISGeocoding.Invalid_Single_Address_Line, nameof(parameters.SingleLineAddress)); } var uriBuilder = new UriBuilder(CandidatesUri); @@ -210,7 +203,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Address")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Address); } if (!string.IsNullOrWhiteSpace(parameters.Address2)) @@ -219,7 +212,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Address2")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Address2); } if (!string.IsNullOrWhiteSpace(parameters.Address3)) @@ -228,7 +221,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Address3")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Address3); } if (!string.IsNullOrWhiteSpace(parameters.Neighbourhood)) @@ -237,7 +230,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Neighbourhood")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Neighbourhood); } if (!string.IsNullOrWhiteSpace(parameters.City)) @@ -246,7 +239,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid City")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_City); } if (!string.IsNullOrWhiteSpace(parameters.Subregion)) @@ -255,7 +248,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Subregion")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Subregion); } if (!string.IsNullOrWhiteSpace(parameters.Region)) @@ -264,7 +257,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Region")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Region); } if (!string.IsNullOrWhiteSpace(parameters.Postal)) @@ -273,7 +266,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Postal")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Postal); } if (!string.IsNullOrWhiteSpace(parameters.PostalExt)) @@ -282,7 +275,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid PostalExt")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_PostalExt); } if (!string.IsNullOrWhiteSpace(parameters.CountryCode)) @@ -291,7 +284,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Country Code")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Country_Code); } if (!string.IsNullOrWhiteSpace(parameters.Category)) @@ -300,7 +293,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Category")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Category); } if (parameters.Location != null) @@ -309,7 +302,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Location")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Location); } if (parameters.MaximumLocations > 0 && parameters.MaximumLocations <= 50) @@ -318,7 +311,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISWarning(_resourceStringProvider.GetString("Invalid Maximum Locations")); + _logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Maximum_Locations); } if (parameters.OutSpatialReference > 0) @@ -327,7 +320,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Out Spatial Reference")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Out_Spatial_Reference); } if (parameters.SearchExtent != null) @@ -336,7 +329,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Search Extent")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Search_Extent); } if (parameters.LanguageCode != null) @@ -345,7 +338,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Language Code")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Language_Code); } if (parameters.LocationType >= 0) @@ -354,7 +347,7 @@ internal async Task BuildPlaceCandidateRequest(PlaceCandidateParameters par } else { - _logger.ArcGISWarning(_resourceStringProvider.GetString("Invalid Location Type")); + _logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Location_Type); } AddStorageParameter(parameters, ref query); @@ -380,9 +373,8 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio if (string.IsNullOrWhiteSpace(parameters.Text)) { - var error = _resourceStringProvider.GetString("Invalid Text"); - _logger.ArcGISError(error); - throw new ArgumentException(error, nameof(parameters.Text)); + _logger.ArcGISError(Resources.Services.ArcGISGeocoding.Invalid_Text); + throw new ArgumentException(Resources.Services.ArcGISGeocoding.Invalid_Text, nameof(parameters.Text)); } query = query.Add("text", parameters.Text); @@ -393,7 +385,7 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Location")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Location); } if (!string.IsNullOrWhiteSpace(parameters.Category)) @@ -402,7 +394,7 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Category")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Category); } if (parameters.SearchExtent != null) @@ -411,7 +403,7 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Search Extent")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Search_Extent); } if (parameters.MaximumLocations > 0 && parameters.MaximumLocations < 16) @@ -420,7 +412,7 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio } else { - _logger.ArcGISWarning(_resourceStringProvider.GetString("Invalid Maximum Locations")); + _logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Maximum_Locations); } if (!string.IsNullOrWhiteSpace(parameters.CountryCode)) @@ -429,7 +421,7 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Country Code")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Country_Code); } if (parameters.SourceCountry.Count != 0) @@ -438,7 +430,7 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Source Country")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Source_Country); } if (parameters.PreferredLabelValue >= 0) @@ -447,7 +439,7 @@ internal Task BuildSuggestRequest(SuggestParameters parameters, Cancellatio } else { - _logger.ArcGISWarning(_resourceStringProvider.GetString("Invalid Preferred Label Value")); + _logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Preferred_Label_Value); } uriBuilder.AddQuery(query); @@ -469,9 +461,8 @@ internal async Task BuildReverseGeocodingRequest(ReverseGeocodingParameters if (parameters.Location is null) { - var error = _resourceStringProvider.GetString("Invalid Location Error"); - _logger.ArcGISError(error); - throw new ArgumentException(error, nameof(parameters.Location)); + _logger.ArcGISError(Resources.Services.ArcGISGeocoding.Invalid_Location_Error); + throw new ArgumentException(Resources.Services.ArcGISGeocoding.Invalid_Location_Error, nameof(parameters.Location)); } query = query.Add("location", parameters.Location.ToString()); @@ -482,7 +473,7 @@ internal async Task BuildReverseGeocodingRequest(ReverseGeocodingParameters } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Out Spatial Reference")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Out_Spatial_Reference); } if (parameters.LanguageCode != null) @@ -491,7 +482,7 @@ internal async Task BuildReverseGeocodingRequest(ReverseGeocodingParameters } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Language Code")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Language_Code); } if (parameters.FeatureTypes != null) @@ -506,7 +497,7 @@ internal async Task BuildReverseGeocodingRequest(ReverseGeocodingParameters } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Feature Types")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Feature_Types); } if (parameters.LocationType >= 0) @@ -515,7 +506,7 @@ internal async Task BuildReverseGeocodingRequest(ReverseGeocodingParameters } else { - _logger.ArcGISWarning(_resourceStringProvider.GetString("Invalid Location Type")); + _logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Location_Type); } if (parameters.PreferredLabelValue >= 0) @@ -524,7 +515,7 @@ internal async Task BuildReverseGeocodingRequest(ReverseGeocodingParameters } else { - _logger.ArcGISWarning(_resourceStringProvider.GetString("Invalid Preferred Label Value")); + _logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Preferred_Label_Value); } AddStorageParameter(parameters, ref query); @@ -550,9 +541,8 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C if (parameters.AddressAttributes is null || parameters.AddressAttributes.Count == 0) { - var error = _resourceStringProvider.GetString("Invalid Address Attributes"); - _logger.ArcGISError(error); - throw new ArgumentException(error, nameof(parameters.AddressAttributes)); + _logger.ArcGISError(Resources.Services.ArcGISGeocoding.Invalid_Address_Attributes); + throw new ArgumentException(Resources.Services.ArcGISGeocoding.Invalid_Address_Attributes, nameof(parameters.AddressAttributes)); } List attributes = new List(); @@ -587,7 +577,7 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Category")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Category); } if (parameters.SourceCountry.Count != 0) @@ -596,7 +586,7 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Source Country")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Source_Country); } if (parameters.OutSpatialReference > 0) @@ -605,7 +595,7 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Out Spatial Reference")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Out_Spatial_Reference); } if (parameters.SearchExtent != null) @@ -614,7 +604,7 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Search Extent")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Search_Extent); } if (parameters.LanguageCode != null) @@ -623,7 +613,7 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C } else { - _logger.ArcGISDebug(_resourceStringProvider.GetString("Invalid Language Code")); + _logger.ArcGISDebug(Resources.Services.ArcGISGeocoding.Invalid_Language_Code); } if (parameters.LocationType >= 0) @@ -632,7 +622,7 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C } else { - _logger.ArcGISWarning(_resourceStringProvider.GetString("Invalid Location Type")); + _logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Location_Type); } if (parameters.PreferredLabelValue >= 0) @@ -641,7 +631,7 @@ internal async Task BuildGeocodingRequest(GeocodingParameters parameters, C } else { - _logger.ArcGISWarning(_resourceStringProvider.GetString("Invalid Preferred Label Value")); + _logger.ArcGISWarning(Resources.Services.ArcGISGeocoding.Invalid_Preferred_Label_Value); } query = await AddArcGISToken(query, cancellationToken).ConfigureAwait(false); diff --git a/src/Geo.Bing/Abstractions/IBingGeocoding.cs b/src/Geo.Bing/Abstractions/IBingGeocoding.cs index 6e1292c..7b97fd8 100644 --- a/src/Geo.Bing/Abstractions/IBingGeocoding.cs +++ b/src/Geo.Bing/Abstractions/IBingGeocoding.cs @@ -7,9 +7,9 @@ namespace Geo.Bing.Abstractions { using System.Threading; using System.Threading.Tasks; - using Geo.Bing.Models.Exceptions; using Geo.Bing.Models.Parameters; using Geo.Bing.Models.Responses; + using Geo.Core.Models.Exceptions; /// /// An interface for calling the Bing geocoding API. @@ -22,7 +22,7 @@ public interface IBingGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Bing. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task GeocodingAsync(GeocodingParameters parameters, CancellationToken cancellationToken = default); /// @@ -31,7 +31,7 @@ public interface IBingGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Bing. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task ReverseGeocodingAsync(ReverseGeocodingParameters parameters, CancellationToken cancellationToken = default); /// @@ -40,7 +40,7 @@ public interface IBingGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Bing. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task AddressGeocodingAsync(AddressGeocodingParameters parameters, CancellationToken cancellationToken = default); } } diff --git a/src/Geo.Bing/DependencyInjection/ServiceCollectionExtensions.cs b/src/Geo.Bing/DependencyInjection/ServiceCollectionExtensions.cs index c468b5c..70f58ed 100644 --- a/src/Geo.Bing/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Geo.Bing/DependencyInjection/ServiceCollectionExtensions.cs @@ -10,7 +10,6 @@ namespace Geo.Bing.DependencyInjection using Geo.Bing.Abstractions; using Geo.Bing.Models; using Geo.Bing.Services; - using Geo.Core.DependencyInjection; using Microsoft.Extensions.DependencyInjection; /// @@ -37,8 +36,6 @@ public static IHttpClientBuilder AddBingServices( Action optionsBuilder, Action configureClient = null) { - services.AddCoreServices(); - if (optionsBuilder != null) { var options = new BingOptionsBuilder(); diff --git a/src/Geo.Bing/Geo.Bing.csproj b/src/Geo.Bing/Geo.Bing.csproj index 88622aa..395bb02 100644 --- a/src/Geo.Bing/Geo.Bing.csproj +++ b/src/Geo.Bing/Geo.Bing.csproj @@ -10,6 +10,7 @@ MIT https://github.com/JustinCanton/Geo.NET true + README.md @@ -33,4 +34,11 @@ + + + True + \ + + + diff --git a/src/Geo.Bing/Models/Exceptions/BingException.cs b/src/Geo.Bing/Models/Exceptions/BingException.cs deleted file mode 100644 index 760d654..0000000 --- a/src/Geo.Bing/Models/Exceptions/BingException.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Bing.Models.Exceptions -{ - using System; - using System.Globalization; - using System.Net.Http; - using System.Text.Json; - using System.Threading.Tasks; - using Geo.Core.Models.Exceptions; - - /// - /// A wrapper exception for any exceptions thrown in the Bing functionality. The current exceptions wrapped by this exception are listed. - /// - /// Thrown when the parameter object is null or the request uri is null. - /// Thrown when the required parameter for the Google request is null or invalid. - /// - /// Thrown when the request failed due to an underlying issue such as network connectivity, - /// DNS failure, server certificate validation or timeout. - /// - /// Thrown when the Bing request is cancelled. - /// Thrown when when an error occurs during JSON deserialization. - public sealed class BingException : GeoCoreException - { - private const string DefaultMessage = "{0} See the inner exception for more information."; - - /// - /// Initializes a new instance of the class. - /// - public BingException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public BingException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - /// The exception that is the cause of the current exception. - public BingException(string message, Exception inner) - : base(string.Format(CultureInfo.InvariantCulture, DefaultMessage, message), inner) - { - } - } -} diff --git a/src/Geo.Bing/Services/BingGeocoding.cs b/src/Geo.Bing/Services/BingGeocoding.cs index 5bac046..5ac06dd 100644 --- a/src/Geo.Bing/Services/BingGeocoding.cs +++ b/src/Geo.Bing/Services/BingGeocoding.cs @@ -12,24 +12,22 @@ namespace Geo.Bing.Services using System.Threading; using System.Threading.Tasks; using Geo.Bing.Abstractions; - using Geo.Bing.Models.Exceptions; using Geo.Bing.Models.Parameters; using Geo.Bing.Models.Responses; using Geo.Core; using Geo.Core.Extensions; + using Geo.Core.Models.Exceptions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; /// /// A service to call the Bing geocoding API. /// - public class BingGeocoding : ClientExecutor, IBingGeocoding + public class BingGeocoding : GeoClient, IBingGeocoding { - private const string ApiName = "Bing"; private const string BaseUri = "http://dev.virtualearth.net/REST/v1/Locations"; private readonly IBingKeyContainer _keyContainer; - private readonly IGeoNETResourceStringProvider _resourceStringProvider; private readonly ILogger _logger; /// @@ -37,22 +35,20 @@ public class BingGeocoding : ClientExecutor, IBingGeocoding /// /// A used for placing calls to the Bing Geocoding API. /// An used for fetching the Bing key. - /// An used to provide exceptions based on an exception type. - /// An used to create a resource string provider for log or exception messages. /// An used to create a logger used for logging information. public BingGeocoding( HttpClient client, IBingKeyContainer keyContainer, - IGeoNETExceptionProvider exceptionProvider, - IGeoNETResourceStringProviderFactory resourceStringProviderFactory, ILoggerFactory loggerFactory = null) - : base(client, exceptionProvider, resourceStringProviderFactory, loggerFactory) + : base(client, loggerFactory) { _keyContainer = keyContainer ?? throw new ArgumentNullException(nameof(keyContainer)); - _resourceStringProvider = resourceStringProviderFactory?.CreateResourceStringProvider() ?? throw new ArgumentNullException(nameof(resourceStringProviderFactory)); _logger = loggerFactory?.CreateLogger() ?? NullLogger.Instance; } + /// + protected override string ApiName => "Bing"; + /// public async Task GeocodingAsync( GeocodingParameters parameters, @@ -60,7 +56,7 @@ public async Task GeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildGeocodingRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -70,7 +66,7 @@ public async Task ReverseGeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildReverseGeocodingRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -78,7 +74,7 @@ public async Task AddressGeocodingAsync(AddressGeocodingParameters par { var uri = ValidateAndBuildUri(parameters, BuildAddressGeocodingRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -93,9 +89,8 @@ internal Uri ValidateAndBuildUri(TParameters parameters, Func(TParameters parameters, Func -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core -{ - using System; - using Geo.Core.Models.Exceptions; - - /// - /// An interface used to provide an exception based on the exception type. - /// - public interface IGeoNETExceptionProvider - { - /// - /// Gets an exception of type . - /// - /// The type of the exception to get. - /// The message the exception should have. - /// Optional. The inner exception to include in the exception. - /// An exception of type . - TException GetException(string message, Exception innerException = null) - where TException : GeoCoreException; - } -} diff --git a/src/Geo.Core/Abstractions/IGeoNETResourceStringProvider.cs b/src/Geo.Core/Abstractions/IGeoNETResourceStringProvider.cs deleted file mode 100644 index ef81752..0000000 --- a/src/Geo.Core/Abstractions/IGeoNETResourceStringProvider.cs +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core -{ - /// - /// A provider that reads resource files and returns strings. - /// - public interface IGeoNETResourceStringProvider - { - /// - /// Gets a formatted resource string. - /// - /// The name of the resource string to fetch. - /// Optional. Parameter arguments corresponding to the parameters of the resource string. - /// A formatted resource string. - string GetString(string resourceName, params object[] args); - } -} diff --git a/src/Geo.Core/Abstractions/IGeoNETResourceStringProviderFactory.cs b/src/Geo.Core/Abstractions/IGeoNETResourceStringProviderFactory.cs deleted file mode 100644 index bea47ac..0000000 --- a/src/Geo.Core/Abstractions/IGeoNETResourceStringProviderFactory.cs +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core -{ - using System; - using System.Reflection; - - /// - /// A factory for creating . - /// - public interface IGeoNETResourceStringProviderFactory - { - /// - /// Creates an based on a type. - /// - /// The type of the resource to create an for. - /// An . - IGeoNETResourceStringProvider CreateResourceStringProvider(); - - /// - /// Creates an based on a type. - /// - /// The type of the resource to create an for. - /// An . - IGeoNETResourceStringProvider CreateResourceStringProvider(Type resourceType); - - /// - /// Creates an based on the resouce file name and assembly. - /// - /// The name of the resource file. - /// Optional. The assembly the resource file is located in. If not passed in, the current assembly will be used. - /// An . - IGeoNETResourceStringProvider CreateResourceStringProvider(string resourceFileName, Assembly assembly = null); - } -} diff --git a/src/Geo.Core/Models/CallResult.cs b/src/Geo.Core/CallResult.cs similarity index 87% rename from src/Geo.Core/Models/CallResult.cs rename to src/Geo.Core/CallResult.cs index 38cbdf9..3f5c9e4 100644 --- a/src/Geo.Core/Models/CallResult.cs +++ b/src/Geo.Core/CallResult.cs @@ -3,7 +3,7 @@ // Licensed under the MIT license. See the LICENSE file in the solution root for full license information. // -namespace Geo.Core.Models +namespace Geo.Core { using System.Net; @@ -19,13 +19,11 @@ internal class CallResult /// /// The result from the call. /// The status code of the call. - /// The string body of the call. - public CallResult(TResult result, HttpStatusCode statusCode, string body) + public CallResult(TResult result, HttpStatusCode statusCode) { IsSuccessful = true; Result = result; StatusCode = statusCode; - Body = body; } /// @@ -36,7 +34,6 @@ public CallResult(TResult result, HttpStatusCode statusCode, string body) public CallResult(HttpStatusCode statusCode, string body) { IsSuccessful = false; - Result = null; StatusCode = statusCode; Body = body; } @@ -49,7 +46,11 @@ public CallResult(HttpStatusCode statusCode, string body) /// /// Gets the result of the call. /// - public TResult Result { get; } +#if NETSTANDARD2_0 + public TResult Result { get; } = null; +#else + public TResult? Result { get; } = null; +#endif /// /// Gets the status code resulting from the call. @@ -59,6 +60,10 @@ public CallResult(HttpStatusCode statusCode, string body) /// /// Gets the body of the result. /// - public string Body { get; } +#if NETSTANDARD2_0 + public string Body { get; } = null; +#else + public string? Body { get; } = null; +#endif } } diff --git a/src/Geo.Core/ClientExecutor.cs b/src/Geo.Core/ClientExecutor.cs deleted file mode 100644 index af2b629..0000000 --- a/src/Geo.Core/ClientExecutor.cs +++ /dev/null @@ -1,146 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core -{ - using System; - using System.Net.Http; - using System.Text.Json; - using System.Threading; - using System.Threading.Tasks; - using Geo.Core.Models; - using Geo.Core.Models.Exceptions; - using Microsoft.Extensions.Logging; - using Microsoft.Extensions.Logging.Abstractions; - - /// - /// A base class used for calls to APIs. - /// - public class ClientExecutor - { - private readonly HttpClient _client; - private readonly IGeoNETExceptionProvider _exceptionProvider; - private readonly IGeoNETResourceStringProvider _resourceStringProvider; - private readonly ILogger _logger; - - /// - /// Initializes a new instance of the class. - /// - /// A used for placing calls to the APIs. - /// An used to provide exceptions based on an exception type. - /// An used to create a resource string provider for log or exception messages. - /// An used to create a logger used for logging information. - public ClientExecutor( - HttpClient client, - IGeoNETExceptionProvider exceptionProvider, - IGeoNETResourceStringProviderFactory resourceStringProviderFactory, - ILoggerFactory loggerFactory = null) - { - _client = client ?? throw new ArgumentNullException(nameof(client)); - _exceptionProvider = exceptionProvider ?? throw new ArgumentNullException(nameof(exceptionProvider)); - _resourceStringProvider = resourceStringProviderFactory?.CreateResourceStringProvider() ?? throw new ArgumentNullException(nameof(resourceStringProviderFactory)); - _logger = loggerFactory?.CreateLogger() ?? NullLogger.Instance; - } - - /// - /// Places a call to the API based on a uri. - /// - /// The return type to parse the response into. - /// The exception type to return in case of any failure. - /// The to call. - /// The name of the API being called for exception logging purposes. - /// A used for cancelling the request. - /// A . - /// An exception of type thrown when any exception occurs and wraps the original exception. - public async Task CallAsync(Uri uri, string apiName, CancellationToken cancellationToken = default) - where TResult : class - where TException : GeoCoreException - { - if (uri is null) - { - throw new ArgumentNullException(nameof(uri)); - } - - CallResult response; - - try - { - response = await CallAsync(uri, cancellationToken).ConfigureAwait(false); - } - catch (ArgumentNullException ex) - { - throw _exceptionProvider.GetException(_resourceStringProvider.GetString("Null Uri", apiName), ex); - } - catch (InvalidOperationException ex) - { - throw _exceptionProvider.GetException(_resourceStringProvider.GetString("Invalid Uri", apiName), ex); - } - catch (HttpRequestException ex) - { - throw _exceptionProvider.GetException(_resourceStringProvider.GetString("Request Failed", apiName), ex); - } - catch (TaskCanceledException ex) - { - throw _exceptionProvider.GetException(_resourceStringProvider.GetString("Request Cancelled", apiName), ex); - } - catch (JsonException ex) - { - throw _exceptionProvider.GetException(_resourceStringProvider.GetString("Serializer Failed To Parse", apiName), ex); - } - catch (Exception ex) - { - throw _exceptionProvider.GetException(_resourceStringProvider.GetString("Request Failed Exception", apiName), ex); - } - - if (!response.IsSuccessful) - { - var ex = _exceptionProvider.GetException(_resourceStringProvider.GetString("Request Failure", apiName)); - ex.Data.Add("uri", uri); - ex.Data.Add("responseStatusCode", response.StatusCode); - ex.Data.Add("responseBody", response.Body); - - _logger.ApiCallFailed(uri, ex); - - throw ex; - } - - return response.Result; - } - - /// - /// Places a call to the API based on a uri. - /// - /// The return type to parse the response into. - /// The to call. - /// A used for cancelling the request. - /// A named with the Result if successful or the JSON string if unsuccessful. - /// Thrown when the request uri is null. - /// Thrown when the request uri is invalid. - /// - /// Thrown when the request failed due to an underlying issue such as network connectivity, - /// DNS failure, server certificate validation or timeout. - /// - /// Thrown when the request is cancelled. - /// Thrown when when an error occurs during JSON deserialization. - internal async Task> CallAsync(Uri uri, CancellationToken cancellationToken = default) - where TResult : class - { - var response = await _client.GetAsync(uri, cancellationToken).ConfigureAwait(false); - -#if NET6_0_OR_GREATER - var json = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); -#else - var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false); -#endif - - if (!response.IsSuccessStatusCode) - { - return new CallResult(response.StatusCode, json); - } - - return new CallResult(JsonSerializer.Deserialize(json), response.StatusCode, json); - } - } -} diff --git a/src/Geo.Core/DependencyInjection/ServiceCollectionExtensions.cs b/src/Geo.Core/DependencyInjection/ServiceCollectionExtensions.cs deleted file mode 100644 index 35bfa24..0000000 --- a/src/Geo.Core/DependencyInjection/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core.DependencyInjection -{ - using System; - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.DependencyInjection.Extensions; - - /// - /// Extension methods for the class. - /// - public static class ServiceCollectionExtensions - { - /// - /// Adds the Core services to the service collection. - /// - /// Adds the services: - /// - /// - /// - /// - /// - /// - /// An to add the Core services to. - /// The for chaining. - /// Thrown if is null. - public static IServiceCollection AddCoreServices(this IServiceCollection services) - { - if (services == null) - { - throw new ArgumentNullException(nameof(services)); - } - - services.TryAddTransient(); - services.TryAddTransient(); - - return services; - } - } -} diff --git a/src/Geo.Core/Extensions/LoggerExtensions.cs b/src/Geo.Core/Extensions/LoggerExtensions.cs index bdd393f..4fdb57a 100644 --- a/src/Geo.Core/Extensions/LoggerExtensions.cs +++ b/src/Geo.Core/Extensions/LoggerExtensions.cs @@ -15,11 +15,11 @@ internal static class LoggerExtensions { private static readonly Action _apiCallFailed = LoggerMessage.Define( LogLevel.Error, - new EventId(1, nameof(ClientExecutor)), - "ClientExecutor: The call to the API {URI} failed."); + new EventId(1, nameof(GeoClient)), + "GeoClient: The call to the API {URI} failed."); /// - /// "ClientExecutor: The call to the API {API} failed.". + /// "GeoClient: The call to the API {API} failed.". /// /// An used to log the error message. /// The uri that failed. diff --git a/src/Geo.Core/Geo.Core.csproj b/src/Geo.Core/Geo.Core.csproj index e872bc1..a762b8c 100644 --- a/src/Geo.Core/Geo.Core.csproj +++ b/src/Geo.Core/Geo.Core.csproj @@ -35,17 +35,17 @@ - + True True - ClientExecutor.resx + GeoClient.resx - + ResXFileCodeGenerator - ClientExecutor.Designer.cs + GeoClient.Designer.cs diff --git a/src/Geo.Core/GeoClient.cs b/src/Geo.Core/GeoClient.cs new file mode 100644 index 0000000..572af97 --- /dev/null +++ b/src/Geo.Core/GeoClient.cs @@ -0,0 +1,299 @@ +// +// Copyright (c) Geo.NET. +// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. +// + +namespace Geo.Core +{ + using System; + using System.Globalization; + using System.Net.Http; + using System.Text; + using System.Text.Json; + using System.Text.Json.Serialization; + using System.Threading; + using System.Threading.Tasks; + using Geo.Core.Models.Exceptions; + using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Logging.Abstractions; + + /// + /// A base class used for calls to APIs. + /// + public abstract class GeoClient + { + private static readonly JsonSerializerOptions _options = GetJsonSerializerOptions(); + + private readonly HttpClient _client; + private readonly ILogger _logger; + + /// + /// Initializes a new instance of the class. + /// + /// A used for placing calls to the APIs. + /// An used to create a logger used for logging information. + protected GeoClient( + HttpClient client, +#if NETSTANDARD2_0 + ILoggerFactory loggerFactory = null) +#else + ILoggerFactory? loggerFactory = null) +#endif + { + Resources.GeoClient.Culture = CultureInfo.InvariantCulture; + _client = client ?? throw new ArgumentNullException(nameof(client)); + _logger = loggerFactory?.CreateLogger() ?? NullLogger.Instance; + } + + /// + /// Gets the name of the API being called for exception logging purposes. + /// + protected abstract string ApiName { get; } + + /// + /// Places a call to an API based on a uri. + /// + /// The return type to parse the response into. + /// The to call. + /// A used for cancelling the request. + /// A . + /// An exception of type thrown when any exception occurs and wraps the original exception. + public Task GetAsync( + Uri uri, + CancellationToken cancellationToken = default) + where TResult : class + { + if (uri is null) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Null_Uri, ApiName), new ArgumentNullException(nameof(uri))); + } + + return CallAsync(uri, HttpMethod.Get, null, cancellationToken); + } + + /// + /// Places a call to an API based on a uri. + /// + /// The type of the . + /// The return type to parse the response into. + /// The to call. + /// The body to include in the POST request. + /// A used for cancelling the request. + /// A . + /// An exception of type thrown when any exception occurs and wraps the original exception. + public Task PostAsync( + Uri uri, + TBody body, + CancellationToken cancellationToken = default) + where TBody : class + where TResult : class + { + if (uri is null) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Null_Uri, ApiName), new ArgumentNullException(nameof(uri))); + } + + if (body is null) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Null_Body, ApiName), new ArgumentNullException(nameof(body))); + } + + return PostInternalAsync(uri, body, cancellationToken); + } + + /// + /// Generates a default . + /// + /// The default . + internal static JsonSerializerOptions GetJsonSerializerOptions() + { + var options = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + }; + + return options; + } + + /// + /// Parses an to a . + /// + /// The return type to parse the response into. + /// The to parse. + /// A used for cancelling the request. + /// A of containing the result of the parsing. + /// Thrown when when an error occurs during JSON deserialization. + internal static async Task> ParseResponseAsync( + HttpResponseMessage response, + CancellationToken cancellationToken) + where TResult : class + { + if (!response.IsSuccessStatusCode) + { +#if NETSTANDARD2_0 + return new CallResult(response.StatusCode, await response.Content.ReadAsStringAsync().ConfigureAwait(false)); +#else + return new CallResult(response.StatusCode, await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false)); +#endif + } + +#if NETSTANDARD2_0 + var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false); +#else + var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false); +#endif + +#if NETSTANDARD2_0 + return new CallResult(await JsonSerializer.DeserializeAsync(stream, _options, cancellationToken).ConfigureAwait(false), response.StatusCode); +#else + return new CallResult((await JsonSerializer.DeserializeAsync(stream, _options, cancellationToken).ConfigureAwait(false))!, response.StatusCode); +#endif + } + + /// + /// An asynchronous call to an API based on a uri. + /// + /// The type of the . + /// The return type to parse the response into. + /// The to call. + /// The body to include in the POST request. + /// A used for cancelling the request. + /// A . + /// An exception of type thrown when any exception occurs and wraps the original exception. + internal async Task PostInternalAsync( + Uri uri, + TBody body, + CancellationToken cancellationToken = default) + where TBody : class + where TResult : class + { + var payload = JsonSerializer.Serialize(body, typeof(TBody), _options); + using (var content = new StringContent(payload, Encoding.UTF8, "application/json")) + { + return await CallAsync(uri, HttpMethod.Post, content, cancellationToken).ConfigureAwait(false); + } + } + + /// + /// Places a call to the API based on a uri. + /// + /// The return type to parse the response into. + /// The to call. + /// The http method to use when calling the API. + /// The content to pass when performing a POST request. + /// A used for cancelling the request. + /// A . + /// An exception of type thrown when any exception occurs and wraps the original exception. + internal async Task CallAsync( + Uri uri, + HttpMethod method, +#if NETSTANDARD2_0 + HttpContent content, +#else + HttpContent? content, +#endif + CancellationToken cancellationToken) + where TResult : class + { + HttpResponseMessage message; + + try + { + message = await HttpCallAsync(uri, method, content, cancellationToken).ConfigureAwait(false); + } + catch (InvalidOperationException ex) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Invalid_Uri, ApiName), ex); + } + catch (HttpRequestException ex) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Request_Failed, ApiName), ex); + } + catch (TaskCanceledException ex) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Request_Cancelled, ApiName), ex); + } + catch (Exception ex) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Request_Failed_Exception, ApiName), ex); + } + + CallResult response; + + try + { + response = await ParseResponseAsync(message, cancellationToken).ConfigureAwait(false); + } + catch (JsonException ex) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Reader_Failed_To_Parse, ApiName), ex); + } + catch (Exception ex) + { + throw new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Parser_Failed, ApiName), ex); + } + + if (!response.IsSuccessful) + { + var ex = new GeoNETException(string.Format(CultureInfo.InvariantCulture, Resources.GeoClient.Request_Failed, ApiName)); + ex.Data.Add("uri", uri); + + if (method == HttpMethod.Post && content != null) + { +#if NETSTANDARD2_0 + ex.Data.Add("requestBody", await content.ReadAsStringAsync().ConfigureAwait(false)); +#else + ex.Data.Add("requestBody", await content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false)); +#endif + } + + ex.Data.Add("responseStatusCode", response.StatusCode); + ex.Data.Add("responseBody", response.Body); + + _logger.ApiCallFailed(uri, ex); + + throw ex; + } + +#if NETSTANDARD2_0 + return response.Result; +#else + return response.Result!; +#endif + } + + /// + /// Places a call to the API based on a uri. + /// + /// The to call. + /// The http method to use when calling the API. + /// The content to pass when performing a POST request. + /// A used for cancelling the request. + /// A containing the response from the API. + /// Thrown when the request uri is invalid. + /// + /// Thrown when the request failed due to an underlying issue such as network connectivity, + /// DNS failure, server certificate validation or timeout. + /// + /// Thrown when the request is cancelled. + internal async Task HttpCallAsync( + Uri uri, + HttpMethod method, +#if NETSTANDARD2_0 + HttpContent content, +#else + HttpContent? content, +#endif + CancellationToken cancellationToken) + { + if (method.Method == HttpMethod.Get.Method) + { + return await _client.GetAsync(uri, cancellationToken).ConfigureAwait(false); + } + else + { + return await _client.PostAsync(uri, content, cancellationToken).ConfigureAwait(false); + } + } + } +} diff --git a/src/Geo.Core/Models/Exceptions/GeoCoreException.cs b/src/Geo.Core/GeoNETException.cs similarity index 71% rename from src/Geo.Core/Models/Exceptions/GeoCoreException.cs rename to src/Geo.Core/GeoNETException.cs index c95f0eb..1ed6336 100644 --- a/src/Geo.Core/Models/Exceptions/GeoCoreException.cs +++ b/src/Geo.Core/GeoNETException.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) Geo.NET. // Licensed under the MIT license. See the LICENSE file in the solution root for full license information. // @@ -12,31 +12,33 @@ namespace Geo.Core.Models.Exceptions /// /// A base exception typ eused by all derived exceptions, which overrides the ToString method to display the Data in the exception as well. /// - public abstract class GeoCoreException : Exception + public sealed class GeoNETException : Exception { + private const string DefaultMessage = "{0} See the inner exception for more information."; + /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - protected GeoCoreException() + public GeoNETException() { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The message that describes the error. - protected GeoCoreException(string message) + public GeoNETException(string message) : base(message) { } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The message that describes the error. /// The exception that is the cause of the current exception. - protected GeoCoreException(string message, Exception inner) - : base(message, inner) + public GeoNETException(string message, Exception inner) + : base(string.Format(CultureInfo.InvariantCulture, DefaultMessage, message), inner) { } diff --git a/src/Geo.Core/GeoNETExceptionProvider.cs b/src/Geo.Core/GeoNETExceptionProvider.cs deleted file mode 100644 index 483386c..0000000 --- a/src/Geo.Core/GeoNETExceptionProvider.cs +++ /dev/null @@ -1,101 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core -{ - using System; - using System.Collections.Concurrent; - using System.Collections.Generic; - using System.Linq.Expressions; - using Geo.Core.Models.Exceptions; - - /// - /// Used to provide an exception based on the exception type. - /// - public sealed class GeoNETExceptionProvider : IGeoNETExceptionProvider - { - private static readonly ConcurrentDictionary> _cachedInnerExceptionDelegates = new ConcurrentDictionary>(); - private static readonly ConcurrentDictionary> _cachedExceptionDelegates = new ConcurrentDictionary>(); - - /// - public TException GetException(string message, Exception innerException = null) - where TException : GeoCoreException - { - if (innerException == null) - { - var exceptionConstructor = GetExceptionConstructor(typeof(TException)); - return exceptionConstructor(message) as TException; - } - else - { - var exceptionConstructor = GetInnerExceptionConstructor(typeof(TException)); - return exceptionConstructor(message, innerException) as TException; - } - } - - private static Func GetInnerExceptionConstructor(Type type) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - - if (_cachedInnerExceptionDelegates.TryGetValue(type, out var cachedConstructor)) - { - return cachedConstructor; - } - - var function = GetInnerExceptionDelegate(type); - - return _cachedInnerExceptionDelegates.AddOrUpdate(type, function, (key, value) => function); - } - - private static Func GetExceptionConstructor(Type type) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - - if (_cachedExceptionDelegates.TryGetValue(type, out var cachedConstructor)) - { - return cachedConstructor; - } - - var function = GetExceptionDelegate(type); - - return _cachedExceptionDelegates.AddOrUpdate(type, function, (key, value) => function); - } - - private static Func GetInnerExceptionDelegate(Type type) - { - var constructorParameters = new Type[] { typeof(string), typeof(Exception) }; - var constructor = type.GetConstructor(constructorParameters); - var parameters = new List() - { - Expression.Parameter(typeof(string)), - Expression.Parameter(typeof(Exception)), - }; - - var expression = Expression.New(constructor, parameters); - var lambdaExpression = Expression.Lambda>(expression, parameters); - return lambdaExpression.Compile(); - } - - private static Func GetExceptionDelegate(Type type) - { - var constructorParameters = new Type[] { typeof(string) }; - var constructor = type.GetConstructor(constructorParameters); - var parameters = new List() - { - Expression.Parameter(typeof(string)), - }; - - var expression = Expression.New(constructor, parameters); - var lambdaExpression = Expression.Lambda>(expression, parameters); - return lambdaExpression.Compile(); - } - } -} diff --git a/src/Geo.Core/GeoNETResourceStringProvider.cs b/src/Geo.Core/GeoNETResourceStringProvider.cs deleted file mode 100644 index ca4161f..0000000 --- a/src/Geo.Core/GeoNETResourceStringProvider.cs +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core -{ - using System.Globalization; - using System.Resources; - - /// - /// An implementation for the . - /// - public sealed class GeoNETResourceStringProvider : IGeoNETResourceStringProvider - { - private readonly ResourceManager _resourceManager; - - /// - /// Initializes a new instance of the class. - /// - /// A used to fetch resources. - internal GeoNETResourceStringProvider(ResourceManager resourceManager) - { - _resourceManager = resourceManager; - } - - /// - public string GetString(string resourceName, params object[] args) - { - var resourceString = _resourceManager.GetString(resourceName, CultureInfo.InvariantCulture); - - if ((args?.Length ?? 0) > 0) - { - return string.Format(CultureInfo.InvariantCulture, resourceString, args); - } - - return resourceString; - } - } -} diff --git a/src/Geo.Core/GeoNETResourceStringProviderFactory.cs b/src/Geo.Core/GeoNETResourceStringProviderFactory.cs deleted file mode 100644 index a04617b..0000000 --- a/src/Geo.Core/GeoNETResourceStringProviderFactory.cs +++ /dev/null @@ -1,65 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core -{ - using System; - using System.Collections.Concurrent; - using System.Reflection; - using System.Resources; - - /// - /// An implementation for the . - /// - public sealed class GeoNETResourceStringProviderFactory : IGeoNETResourceStringProviderFactory - { - private static ConcurrentDictionary<(string resourceFileName, Assembly assembly), ResourceManager> _resourceManagers = - new ConcurrentDictionary<(string resourceFileName, Assembly assembly), ResourceManager>(); - - /// - public IGeoNETResourceStringProvider CreateResourceStringProvider() - { - return CreateResourceStringProvider(typeof(TResource)); - } - - /// - public IGeoNETResourceStringProvider CreateResourceStringProvider(Type resourceType) - { - if (resourceType == null) - { - throw new ArgumentNullException(nameof(resourceType)); - } - - return CreateResourceStringProvider(CreateResourceBaseName(resourceType), resourceType.Assembly); - } - - /// - public IGeoNETResourceStringProvider CreateResourceStringProvider(string resourceFileName, Assembly assembly = null) - { - if (string.IsNullOrEmpty(resourceFileName)) - { - throw new ArgumentException("The resource file name cannot be null or empty", nameof(resourceFileName)); - } - - var resourceManager = _resourceManagers.GetOrAdd( - (resourceFileName, assembly), - new ResourceManager(resourceFileName, assembly ?? Assembly.GetCallingAssembly())); - - return new GeoNETResourceStringProvider(resourceManager); - } - - private static string CreateResourceBaseName(Type resourceType) - { - var assemblyName = resourceType.Assembly.GetName().Name; - var resourceName = resourceType.FullName; - var resourceFolderName = assemblyName + ".Resources"; -#if NETSTANDARD2_1_OR_GREATER - return resourceName.Replace(assemblyName, resourceFolderName, StringComparison.InvariantCultureIgnoreCase); -#else - return resourceName.Replace(assemblyName, resourceFolderName); -#endif - } - } -} diff --git a/src/Geo.Core/Resources/ClientExecutor.Designer.cs b/src/Geo.Core/Resources/GeoClient.Designer.cs similarity index 87% rename from src/Geo.Core/Resources/ClientExecutor.Designer.cs rename to src/Geo.Core/Resources/GeoClient.Designer.cs index 7da8fb1..17be7d7 100644 --- a/src/Geo.Core/Resources/ClientExecutor.Designer.cs +++ b/src/Geo.Core/Resources/GeoClient.Designer.cs @@ -22,14 +22,14 @@ namespace Geo.Core.Resources { [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class ClientExecutor { + internal class GeoClient { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal ClientExecutor() { + internal GeoClient() { } /// @@ -39,7 +39,7 @@ internal ClientExecutor() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Geo.Core.Resources.ClientExecutor", typeof(ClientExecutor).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Geo.Core.Resources.GeoClient", typeof(GeoClient).Assembly); resourceMan = temp; } return resourceMan; @@ -69,6 +69,15 @@ internal static string Invalid_Uri { } } + /// + /// Looks up a localized string similar to The {0} body is invalid.. + /// + internal static string Null_Body { + get { + return ResourceManager.GetString("Null Body", resourceCulture); + } + } + /// /// Looks up a localized string similar to The {0} uri is null.. /// @@ -78,6 +87,15 @@ internal static string Null_Uri { } } + /// + /// Looks up a localized string similar to The parsing of the call to {0} failed with an exception.. + /// + internal static string Parser_Failed { + get { + return ResourceManager.GetString("Parser Failed", resourceCulture); + } + } + /// /// Looks up a localized string similar to Failed to parse the {0} response properly.. /// diff --git a/src/Geo.Core/Resources/ClientExecutor.resx b/src/Geo.Core/Resources/GeoClient.en.resx similarity index 96% rename from src/Geo.Core/Resources/ClientExecutor.resx rename to src/Geo.Core/Resources/GeoClient.en.resx index afcd9b5..cab8202 100644 --- a/src/Geo.Core/Resources/ClientExecutor.resx +++ b/src/Geo.Core/Resources/GeoClient.en.resx @@ -120,9 +120,15 @@ The {0} uri is invalid. + + The {0} body is invalid. + The {0} uri is null. + + The parsing of the call to {0} failed with an exception. + Failed to parse the {0} response properly. diff --git a/src/Geo.Core/Resources/ClientExecutor.en.resx b/src/Geo.Core/Resources/GeoClient.resx similarity index 96% rename from src/Geo.Core/Resources/ClientExecutor.en.resx rename to src/Geo.Core/Resources/GeoClient.resx index afcd9b5..cab8202 100644 --- a/src/Geo.Core/Resources/ClientExecutor.en.resx +++ b/src/Geo.Core/Resources/GeoClient.resx @@ -120,9 +120,15 @@ The {0} uri is invalid. + + The {0} body is invalid. + The {0} uri is null. + + The parsing of the call to {0} failed with an exception. + Failed to parse the {0} response properly. diff --git a/src/Geo.Google/Abstractions/IGoogleGeocoding.cs b/src/Geo.Google/Abstractions/IGoogleGeocoding.cs index a3a4c2e..46cb966 100644 --- a/src/Geo.Google/Abstractions/IGoogleGeocoding.cs +++ b/src/Geo.Google/Abstractions/IGoogleGeocoding.cs @@ -7,7 +7,7 @@ namespace Geo.Google.Abstractions { using System.Threading; using System.Threading.Tasks; - using Geo.Google.Models.Exceptions; + using Geo.Core.Models.Exceptions; using Geo.Google.Models.Parameters; using Geo.Google.Models.Responses; @@ -22,7 +22,7 @@ public interface IGoogleGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Google. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task GeocodingAsync(GeocodingParameters parameters, CancellationToken cancellationToken = default); /// @@ -31,7 +31,7 @@ public interface IGoogleGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Google. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task ReverseGeocodingAsync(ReverseGeocodingParameters parameters, CancellationToken cancellationToken = default); /// @@ -40,7 +40,7 @@ public interface IGoogleGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Google. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task FindPlacesAsync(FindPlacesParameters parameters, CancellationToken cancellationToken = default); /// @@ -49,7 +49,7 @@ public interface IGoogleGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Google. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task NearbySearchAsync(NearbySearchParameters parameters, CancellationToken cancellationToken = default); /// @@ -58,7 +58,7 @@ public interface IGoogleGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Google. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task TextSearchAsync(TextSearchParameters parameters, CancellationToken cancellationToken = default); /// @@ -67,7 +67,7 @@ public interface IGoogleGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Google. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task DetailsAsync(DetailsParameters parameters, CancellationToken cancellationToken = default); /// @@ -76,7 +76,7 @@ public interface IGoogleGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Google. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task> PlaceAutocompleteAsync(PlacesAutocompleteParameters parameters, CancellationToken cancellationToken = default); /// @@ -85,7 +85,7 @@ public interface IGoogleGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from Google. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task> QueryAutocompleteAsync(QueryAutocompleteParameters parameters, CancellationToken cancellationToken = default); } } diff --git a/src/Geo.Google/DependencyInjection/ServiceCollectionExtensions.cs b/src/Geo.Google/DependencyInjection/ServiceCollectionExtensions.cs index d7b58a7..06af75d 100644 --- a/src/Geo.Google/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Geo.Google/DependencyInjection/ServiceCollectionExtensions.cs @@ -7,7 +7,6 @@ namespace Geo.Google.DependencyInjection { using System; using System.Net.Http; - using Geo.Core.DependencyInjection; using Geo.Google.Abstractions; using Geo.Google.Models; using Geo.Google.Services; @@ -37,8 +36,6 @@ public static IHttpClientBuilder AddGoogleServices( Action optionsBuilder, Action configureClient = null) { - services.AddCoreServices(); - if (optionsBuilder != null) { var options = new GoogleOptionsBuilder(); diff --git a/src/Geo.Google/Geo.Google.csproj b/src/Geo.Google/Geo.Google.csproj index ef3823b..e427e0f 100644 --- a/src/Geo.Google/Geo.Google.csproj +++ b/src/Geo.Google/Geo.Google.csproj @@ -10,6 +10,7 @@ MIT https://github.com/JustinCanton/Geo.NET true + README.md @@ -33,4 +34,11 @@ + + + True + \ + + + diff --git a/src/Geo.Google/Models/Exceptions/GoogleException.cs b/src/Geo.Google/Models/Exceptions/GoogleException.cs deleted file mode 100644 index aebd9a1..0000000 --- a/src/Geo.Google/Models/Exceptions/GoogleException.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Google.Models.Exceptions -{ - using System; - using System.Globalization; - using System.Net.Http; - using System.Text.Json; - using System.Threading.Tasks; - using Geo.Core.Models.Exceptions; - - /// - /// A wrapper exception for any exceptions thrown in the Google functionality. The current exceptions wrapped by this exception are listed. - /// - /// Thrown when the parameter object is null or the request uri is null. - /// Thrown when the required parameter for the Google request is null or invalid. - /// - /// Thrown when the request failed due to an underlying issue such as network connectivity, - /// DNS failure, server certificate validation or timeout. - /// - /// Thrown when the Google request is cancelled. - /// Thrown when when an error occurs during JSON deserialization. - public sealed class GoogleException : GeoCoreException - { - private const string DefaultMessage = "{0} See the inner exception for more information."; - - /// - /// Initializes a new instance of the class. - /// - public GoogleException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public GoogleException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - /// The exception that is the cause of the current exception. - public GoogleException(string message, Exception inner) - : base(string.Format(CultureInfo.InvariantCulture, DefaultMessage, message), inner) - { - } - } -} diff --git a/src/Geo.Google/Services/GoogleGeocoding.cs b/src/Geo.Google/Services/GoogleGeocoding.cs index 80e6752..e2fe413 100644 --- a/src/Geo.Google/Services/GoogleGeocoding.cs +++ b/src/Geo.Google/Services/GoogleGeocoding.cs @@ -14,10 +14,10 @@ namespace Geo.Google.Services using System.Threading.Tasks; using Geo.Core; using Geo.Core.Extensions; + using Geo.Core.Models.Exceptions; using Geo.Google.Abstractions; using Geo.Google.Enums; using Geo.Google.Models; - using Geo.Google.Models.Exceptions; using Geo.Google.Models.Parameters; using Geo.Google.Models.Responses; using Microsoft.Extensions.Logging; @@ -26,9 +26,8 @@ namespace Geo.Google.Services /// /// A service to call the Google geocoding API. /// - public class GoogleGeocoding : ClientExecutor, IGoogleGeocoding + public class GoogleGeocoding : GeoClient, IGoogleGeocoding { - private const string ApiName = "Google"; private const string GeocodingUri = "https://maps.googleapis.com/maps/api/geocode/json"; private const string FindPlaceUri = "https://maps.googleapis.com/maps/api/place/findplacefromtext/json"; private const string NearbySearchUri = "https://maps.googleapis.com/maps/api/place/nearbysearch/json"; @@ -38,7 +37,6 @@ public class GoogleGeocoding : ClientExecutor, IGoogleGeocoding private const string QueryAutocompleteUri = "https://maps.googleapis.com/maps/api/place/queryautocomplete/json"; private readonly IGoogleKeyContainer _keyContainer; - private readonly IGeoNETResourceStringProvider _resourceStringProvider; private readonly ILogger _logger; /// @@ -46,22 +44,20 @@ public class GoogleGeocoding : ClientExecutor, IGoogleGeocoding /// /// A used for placing calls to the Google Geocoding API. /// An used for fetching the Google key. - /// An used to provide exceptions based on an exception type. - /// An used to create a resource string provider for log or exception messages. /// An used to create a logger used for logging information. public GoogleGeocoding( HttpClient client, IGoogleKeyContainer keyContainer, - IGeoNETExceptionProvider exceptionProvider, - IGeoNETResourceStringProviderFactory resourceStringProviderFactory, ILoggerFactory loggerFactory = null) - : base(client, exceptionProvider, resourceStringProviderFactory, loggerFactory) + : base(client, loggerFactory) { _keyContainer = keyContainer ?? throw new ArgumentNullException(nameof(keyContainer)); - _resourceStringProvider = resourceStringProviderFactory?.CreateResourceStringProvider() ?? throw new ArgumentNullException(nameof(resourceStringProviderFactory)); _logger = loggerFactory?.CreateLogger() ?? NullLogger.Instance; } + /// + protected override string ApiName => "Google"; + /// public async Task GeocodingAsync( GeocodingParameters parameters, @@ -69,7 +65,7 @@ public async Task GeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildGeocodingRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -79,7 +75,7 @@ public async Task ReverseGeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildReverseGeocodingRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -89,7 +85,7 @@ public async Task FindPlacesAsync( { var uri = ValidateAndBuildUri(parameters, BuildFindPlaceRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -99,7 +95,7 @@ public async Task NearbySearchAsync( { var uri = ValidateAndBuildUri(parameters, BuildNearbySearchRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -109,7 +105,7 @@ public async Task TextSearchAsync( { var uri = ValidateAndBuildUri(parameters, BuildTextSearchRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -119,7 +115,7 @@ public async Task DetailsAsync( { var uri = ValidateAndBuildUri(parameters, BuildDetailsRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -129,7 +125,7 @@ public async Task> PlaceAutocompleteAsyn { var uri = ValidateAndBuildUri(parameters, BuildPlaceAutocompleteRequest); - return await CallAsync, GoogleException>(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync>(uri, cancellationToken).ConfigureAwait(false); } /// @@ -139,7 +135,7 @@ public async Task> QueryAutocompleteAsyn { var uri = ValidateAndBuildUri(parameters, BuildQueryAutocompleteRequest); - return await CallAsync, GoogleException>(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync>(uri, cancellationToken).ConfigureAwait(false); } /// @@ -173,9 +169,8 @@ internal Uri ValidateAndBuildUri(TParameters parameters, Func(TParameters parameters, Func InputType.PhoneNumber || parameters.InputType < InputType.TextQuery) { - var error = _resourceStringProvider.GetString("Invalid Input Type"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.InputType)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_Input_Type); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_Input_Type, nameof(parameters.InputType)); } query = query.Add("input", parameters.Input); @@ -352,7 +342,7 @@ internal Uri BuildFindPlaceRequest(FindPlacesParameters parameters) } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Fields")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Fields); } if (parameters.LocationBias != null) @@ -369,13 +359,13 @@ internal Uri BuildFindPlaceRequest(FindPlacesParameters parameters) query = query.Add("locationbias", $"rectangle:{boundary}"); break; default: - _logger.GoogleWarning(_resourceStringProvider.GetString("Invalid Location Bias Type")); + _logger.GoogleWarning(Resources.Services.GoogleGeocoding.Invalid_Location_Bias_Type); break; } } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Location Bias")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Location_Bias); } AddBaseParameters(parameters, ref query); @@ -404,32 +394,28 @@ internal Uri BuildNearbySearchRequest(NearbySearchParameters parameters) if (parameters.Location == null) { - var error = _resourceStringProvider.GetString("Invalid Location"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.Location)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_Location); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_Location, nameof(parameters.Location)); } if (parameters.RankBy == RankType.Distance) { if (parameters.Radius > 0) { - var error = _resourceStringProvider.GetString("Invalid RankBy Distance Radius"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.Radius)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_RankBy_Distance_Radius); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_RankBy_Distance_Radius, nameof(parameters.Radius)); } if (string.IsNullOrWhiteSpace(parameters.Keyword) && string.IsNullOrWhiteSpace(parameters.Type)) { - var error = _resourceStringProvider.GetString("Invalid RankBy Distance Request"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.RankBy)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_RankBy_Distance_Request); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_RankBy_Distance_Request, nameof(parameters.RankBy)); } } else if (parameters.Radius <= 0) { - var error = _resourceStringProvider.GetString("Invalid Radius"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.Radius)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_Radius); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_Radius, nameof(parameters.Radius)); } if (!string.IsNullOrWhiteSpace(parameters.Keyword)) @@ -438,7 +424,7 @@ internal Uri BuildNearbySearchRequest(NearbySearchParameters parameters) } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Keyword")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Keyword); } if (parameters.RankBy >= RankType.Prominence && parameters.RankBy <= RankType.Distance) @@ -447,7 +433,7 @@ internal Uri BuildNearbySearchRequest(NearbySearchParameters parameters) } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid RankBy")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_RankBy); } AddBaseSearchParameters(parameters, ref query); @@ -472,9 +458,8 @@ internal Uri BuildTextSearchRequest(TextSearchParameters parameters) if (string.IsNullOrWhiteSpace(parameters.Query)) { - var error = _resourceStringProvider.GetString("Invalid Query"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.Query)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_Query); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_Query, nameof(parameters.Query)); } query = query.Add("query", parameters.Query); @@ -485,7 +470,7 @@ internal Uri BuildTextSearchRequest(TextSearchParameters parameters) } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Region")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Region); } AddBaseSearchParameters(parameters, ref query); @@ -510,9 +495,8 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters) if (string.IsNullOrWhiteSpace(parameters.PlaceId)) { - var error = _resourceStringProvider.GetString("Invalid PlaceId"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.PlaceId)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_PlaceId); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_PlaceId, nameof(parameters.PlaceId)); } query = query.Add("place_id", parameters.PlaceId); @@ -523,7 +507,7 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters) } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Region")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Region); } if (!string.IsNullOrWhiteSpace(parameters.SessionToken)) @@ -532,7 +516,7 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters) } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Session Token")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Session_Token); } if (parameters.Fields != null && parameters.Fields.Count > 0) @@ -541,7 +525,7 @@ internal Uri BuildDetailsRequest(DetailsParameters parameters) } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Fields")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Fields); } AddBaseParameters(parameters, ref query); @@ -566,9 +550,8 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete if (string.IsNullOrWhiteSpace(parameters.Input)) { - var error = _resourceStringProvider.GetString("Invalid Input"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.Input)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_Input); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_Input, nameof(parameters.Input)); } if (!string.IsNullOrWhiteSpace(parameters.SessionToken)) @@ -577,7 +560,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Session Token")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Session_Token); } if (parameters.Origin != null) @@ -586,7 +569,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Origin")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Origin); } if (parameters.Types != null && parameters.Types.Count > 0) @@ -595,7 +578,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Types")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Types); } if (parameters.Components != null) @@ -604,7 +587,7 @@ internal Uri BuildPlaceAutocompleteRequest(PlacesAutocompleteParameters paramete } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Components")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Components); } #pragma warning disable CA1308 // Normalize strings to uppercase @@ -633,9 +616,8 @@ internal Uri BuildQueryAutocompleteRequest(QueryAutocompleteParameters parameter if (string.IsNullOrWhiteSpace(parameters.Input)) { - var error = _resourceStringProvider.GetString("Invalid Input"); - _logger.GoogleError(error); - throw new ArgumentException(error, nameof(parameters.Input)); + _logger.GoogleError(Resources.Services.GoogleGeocoding.Invalid_Input); + throw new ArgumentException(Resources.Services.GoogleGeocoding.Invalid_Input, nameof(parameters.Input)); } AddAutocompleteParameters(parameters, ref query); @@ -660,7 +642,7 @@ internal void AddAutocompleteParameters(QueryAutocompleteParameters parameters, } else { - _logger.GoogleWarning(_resourceStringProvider.GetString("Invalid Offset")); + _logger.GoogleWarning(Resources.Services.GoogleGeocoding.Invalid_Offset); } if (!string.IsNullOrWhiteSpace(parameters.Input)) @@ -669,7 +651,7 @@ internal void AddAutocompleteParameters(QueryAutocompleteParameters parameters, } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Input Info")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Input_Info); } AddCoordinateParameters(parameters, ref query); @@ -688,7 +670,7 @@ internal void AddBaseSearchParameters(BaseSearchParameters parameters, ref Query } else { - _logger.GoogleWarning(_resourceStringProvider.GetString("Invalid Minimum Price")); + _logger.GoogleWarning(Resources.Services.GoogleGeocoding.Invalid_Minimum_Price); } if (parameters.MaximumPrice >= 0 && parameters.MaximumPrice <= 4 && parameters.MinimumPrice <= parameters.MaximumPrice) @@ -697,7 +679,7 @@ internal void AddBaseSearchParameters(BaseSearchParameters parameters, ref Query } else { - _logger.GoogleWarning(_resourceStringProvider.GetString("Invalid Maximum Price")); + _logger.GoogleWarning(Resources.Services.GoogleGeocoding.Invalid_Maximum_Price); } #pragma warning disable CA1308 // Normalize strings to uppercase @@ -710,7 +692,7 @@ internal void AddBaseSearchParameters(BaseSearchParameters parameters, ref Query } else { - _logger.GoogleWarning(_resourceStringProvider.GetString("Invalid Page Token")); + _logger.GoogleWarning(Resources.Services.GoogleGeocoding.Invalid_Page_Token); } if (!string.IsNullOrWhiteSpace(parameters.Type)) @@ -719,7 +701,7 @@ internal void AddBaseSearchParameters(BaseSearchParameters parameters, ref Query } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Type")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Type); } AddCoordinateParameters(parameters, ref query); @@ -738,7 +720,7 @@ internal void AddCoordinateParameters(CoordinateParameters parameters, ref Query } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Location")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Location); } if (parameters.Radius > 0 && parameters.Radius <= 50000) @@ -747,7 +729,7 @@ internal void AddCoordinateParameters(CoordinateParameters parameters, ref Query } else { - _logger.GoogleWarning(_resourceStringProvider.GetString("Invalid Radius Value")); + _logger.GoogleWarning(Resources.Services.GoogleGeocoding.Invalid_Radius_Value); } AddBaseParameters(parameters, ref query); @@ -766,7 +748,7 @@ internal void AddBaseParameters(BaseParameters parameters, ref QueryString query } else { - _logger.GoogleDebug(_resourceStringProvider.GetString("Invalid Language")); + _logger.GoogleDebug(Resources.Services.GoogleGeocoding.Invalid_Language); } } diff --git a/src/Geo.Here/Abstractions/IHereGeocoding.cs b/src/Geo.Here/Abstractions/IHereGeocoding.cs index a6b170f..3f12ad1 100644 --- a/src/Geo.Here/Abstractions/IHereGeocoding.cs +++ b/src/Geo.Here/Abstractions/IHereGeocoding.cs @@ -7,7 +7,7 @@ namespace Geo.Here.Abstractions { using System.Threading; using System.Threading.Tasks; - using Geo.Here.Models.Exceptions; + using Geo.Core.Models.Exceptions; using Geo.Here.Models.Parameters; using Geo.Here.Models.Responses; @@ -22,7 +22,7 @@ public interface IHereGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from HERE. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task GeocodingAsync(GeocodeParameters parameters, CancellationToken cancellationToken = default); /// @@ -31,7 +31,7 @@ public interface IHereGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from HERE. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task ReverseGeocodingAsync(ReverseGeocodeParameters parameters, CancellationToken cancellationToken = default); /// @@ -40,7 +40,7 @@ public interface IHereGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from HERE. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task DiscoverAsync(DiscoverParameters parameters, CancellationToken cancellationToken = default); /// @@ -49,7 +49,7 @@ public interface IHereGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from HERE. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task AutosuggestAsync(AutosuggestParameters parameters, CancellationToken cancellationToken = default); /// @@ -58,7 +58,7 @@ public interface IHereGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from HERE. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task BrowseAsync(BrowseParameters parameters, CancellationToken cancellationToken = default); /// @@ -67,7 +67,7 @@ public interface IHereGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from HERE. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task LookupAsync(LookupParameters parameters, CancellationToken cancellationToken = default); } } diff --git a/src/Geo.Here/DependencyInjection/ServiceCollectionExtensions.cs b/src/Geo.Here/DependencyInjection/ServiceCollectionExtensions.cs index 6c4e542..40c5736 100644 --- a/src/Geo.Here/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Geo.Here/DependencyInjection/ServiceCollectionExtensions.cs @@ -7,7 +7,6 @@ namespace Geo.Here.DependencyInjection { using System; using System.Net.Http; - using Geo.Core.DependencyInjection; using Geo.Here.Abstractions; using Geo.Here.Models; using Geo.Here.Services; @@ -37,8 +36,6 @@ public static IHttpClientBuilder AddHereServices( Action optionsBuilder, Action configureClient = null) { - services.AddCoreServices(); - if (optionsBuilder != null) { var options = new HereOptionsBuilder(); diff --git a/src/Geo.Here/Geo.Here.csproj b/src/Geo.Here/Geo.Here.csproj index d26e18a..b3b0ec8 100644 --- a/src/Geo.Here/Geo.Here.csproj +++ b/src/Geo.Here/Geo.Here.csproj @@ -10,6 +10,7 @@ MIT https://github.com/JustinCanton/Geo.NET true + README.md @@ -33,4 +34,11 @@ + + + True + \ + + + diff --git a/src/Geo.Here/Models/Exceptions/HereException.cs b/src/Geo.Here/Models/Exceptions/HereException.cs deleted file mode 100644 index d97be1a..0000000 --- a/src/Geo.Here/Models/Exceptions/HereException.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Here.Models.Exceptions -{ - using System; - using System.Globalization; - using System.Net.Http; - using System.Text.Json; - using System.Threading.Tasks; - using Geo.Core.Models.Exceptions; - - /// - /// A wrapper exception for any exceptions thrown in the HERE functionality. The current exceptions wrapped by this exception are listed. - /// - /// Thrown when the parameter object is null or the request uri is null. - /// Thrown when the required parameter for the Google request is null or invalid. - /// - /// Thrown when the request failed due to an underlying issue such as network connectivity, - /// DNS failure, server certificate validation or timeout. - /// - /// Thrown when the HERE request is cancelled. - /// Thrown when when an error occurs during JSON deserialization. - public sealed class HereException : GeoCoreException - { - private const string DefaultMessage = "{0} See the inner exception for more information."; - - /// - /// Initializes a new instance of the class. - /// - public HereException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public HereException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - /// The exception that is the cause of the current exception. - public HereException(string message, Exception inner) - : base(string.Format(CultureInfo.InvariantCulture, DefaultMessage, message), inner) - { - } - } -} diff --git a/src/Geo.Here/Services/HereGeocoding.cs b/src/Geo.Here/Services/HereGeocoding.cs index 195c3ca..39cb6c6 100644 --- a/src/Geo.Here/Services/HereGeocoding.cs +++ b/src/Geo.Here/Services/HereGeocoding.cs @@ -13,8 +13,8 @@ namespace Geo.Here.Services using System.Threading.Tasks; using Geo.Core; using Geo.Core.Extensions; + using Geo.Core.Models.Exceptions; using Geo.Here.Abstractions; - using Geo.Here.Models.Exceptions; using Geo.Here.Models.Parameters; using Geo.Here.Models.Responses; using Microsoft.Extensions.Logging; @@ -23,9 +23,8 @@ namespace Geo.Here.Services /// /// A service to call the HERE geocoding API. /// - public class HereGeocoding : ClientExecutor, IHereGeocoding + public class HereGeocoding : GeoClient, IHereGeocoding { - private const string ApiName = "Here"; private const string GeocodeUri = "https://geocode.search.hereapi.com/v1/geocode"; private const string ReverseGeocodeUri = "https://revgeocode.search.hereapi.com/v1/revgeocode"; private const string DiscoverUri = "https://discover.search.hereapi.com/v1/discover"; @@ -34,7 +33,6 @@ public class HereGeocoding : ClientExecutor, IHereGeocoding private const string LookupUri = "https://lookup.search.hereapi.com/v1/lookup"; private readonly IHereKeyContainer _keyContainer; - private readonly IGeoNETResourceStringProvider _resourceStringProvider; private readonly ILogger _logger; /// @@ -42,22 +40,20 @@ public class HereGeocoding : ClientExecutor, IHereGeocoding /// /// A used for placing calls to the HERE Geocoding API. /// An used for fetching the HERE key. - /// An used to provide exceptions based on an exception type. - /// An used to create a resource string provider for log or exception messages. /// An used to create a logger used for logging information. public HereGeocoding( HttpClient client, IHereKeyContainer keyContainer, - IGeoNETExceptionProvider exceptionProvider, - IGeoNETResourceStringProviderFactory resourceStringProviderFactory, ILoggerFactory loggerFactory = null) - : base(client, exceptionProvider, resourceStringProviderFactory, loggerFactory) + : base(client, loggerFactory) { _keyContainer = keyContainer ?? throw new ArgumentNullException(nameof(keyContainer)); - _resourceStringProvider = resourceStringProviderFactory?.CreateResourceStringProvider() ?? throw new ArgumentNullException(nameof(resourceStringProviderFactory)); _logger = loggerFactory?.CreateLogger() ?? NullLogger.Instance; } + /// + protected override string ApiName => "Here"; + /// public async Task GeocodingAsync( GeocodeParameters parameters, @@ -65,7 +61,7 @@ public async Task GeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildGeocodingRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -75,7 +71,7 @@ public async Task ReverseGeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildReverseGeocodingRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -85,7 +81,7 @@ public async Task DiscoverAsync( { var uri = ValidateAndBuildUri(parameters, BuildDiscoverRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -95,7 +91,7 @@ public async Task AutosuggestAsync( { var uri = ValidateAndBuildUri(parameters, BuildAutosuggestRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -105,7 +101,7 @@ public async Task LookupAsync( { var uri = ValidateAndBuildUri(parameters, BuildLookupRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -115,7 +111,7 @@ public async Task BrowseAsync( { var uri = ValidateAndBuildUri(parameters, BuildBrowseRequest); - return await CallAsync(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync(uri, cancellationToken).ConfigureAwait(false); } /// @@ -130,9 +126,8 @@ internal Uri ValidateAndBuildUri(TParameters parameters, Func(TParameters parameters, Func 0) @@ -189,7 +182,7 @@ internal Uri BuildGeocodingRequest(GeocodeParameters parameters) } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid In Country")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_In_Country); } if (parameters.Types.Any()) @@ -198,7 +191,7 @@ internal Uri BuildGeocodingRequest(GeocodeParameters parameters) } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Types")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Types); } AddLocatingParameters(parameters, ref query); @@ -224,9 +217,8 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodeParameters parameters) if ((parameters.At is null && parameters.InCircle is null) || (parameters.At != null && parameters.InCircle != null)) { - var error = _resourceStringProvider.GetString("Invalid Bounding Parameters"); - _logger.HereError(error); - throw new ArgumentException(error, nameof(parameters)); + _logger.HereError(Resources.Services.HereGeocoding.Invalid_Bounding_Parameters); + throw new ArgumentException(Resources.Services.HereGeocoding.Invalid_Bounding_Parameters, nameof(parameters)); } if (parameters.InCircle != null && parameters.InCircle.IsValid()) @@ -235,7 +227,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodeParameters parameters) } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid In Circle")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_In_Circle); } if (parameters.Types.Any()) @@ -244,7 +236,7 @@ internal Uri BuildReverseGeocodingRequest(ReverseGeocodeParameters parameters) } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Types")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Types); } AddLocatingParameters(parameters, ref query); @@ -269,9 +261,8 @@ internal Uri BuildDiscoverRequest(DiscoverParameters parameters) if (string.IsNullOrWhiteSpace(parameters.Query)) { - var error = _resourceStringProvider.GetString("Invalid Query Error"); - _logger.HereError(error); - throw new ArgumentException(error, nameof(parameters.Query)); + _logger.HereError(Resources.Services.HereGeocoding.Invalid_Query_Error); + throw new ArgumentException(Resources.Services.HereGeocoding.Invalid_Query_Error, nameof(parameters.Query)); } query = query.Add("q", parameters.Query); @@ -298,9 +289,8 @@ internal Uri BuildAutosuggestRequest(AutosuggestParameters parameters) if (string.IsNullOrWhiteSpace(parameters.Query)) { - var error = _resourceStringProvider.GetString("Invalid Query Error"); - _logger.HereError(error); - throw new ArgumentException(error, nameof(parameters.Query)); + _logger.HereError(Resources.Services.HereGeocoding.Invalid_Query_Error); + throw new ArgumentException(Resources.Services.HereGeocoding.Invalid_Query_Error, nameof(parameters.Query)); } query = query.Add("q", parameters.Query); @@ -311,7 +301,7 @@ internal Uri BuildAutosuggestRequest(AutosuggestParameters parameters) } else { - _logger.HereWarning(_resourceStringProvider.GetString("Invalid Terms Limit")); + _logger.HereWarning(Resources.Services.HereGeocoding.Invalid_Terms_Limit); } AddBoundingParameters(parameters, ref query); @@ -336,9 +326,8 @@ internal Uri BuildBrowseRequest(BrowseParameters parameters) if (parameters.At is null) { - var error = _resourceStringProvider.GetString("Invalid At"); - _logger.HereError(error); - throw new ArgumentException(error, nameof(parameters.At)); + _logger.HereError(Resources.Services.HereGeocoding.Invalid_At); + throw new ArgumentException(Resources.Services.HereGeocoding.Invalid_At, nameof(parameters.At)); } if (!string.IsNullOrWhiteSpace(parameters.Categories)) @@ -347,7 +336,7 @@ internal Uri BuildBrowseRequest(BrowseParameters parameters) } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Categories")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Categories); } if (!string.IsNullOrWhiteSpace(parameters.Name)) @@ -356,7 +345,7 @@ internal Uri BuildBrowseRequest(BrowseParameters parameters) } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Name")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Name); } AddBoundingParameters(parameters, ref query); @@ -381,9 +370,8 @@ internal Uri BuildLookupRequest(LookupParameters parameters) if (string.IsNullOrWhiteSpace(parameters.Id)) { - var error = _resourceStringProvider.GetString("Invalid Id"); - _logger.HereError(error); - throw new ArgumentException(error, nameof(parameters.Id)); + _logger.HereError(Resources.Services.HereGeocoding.Invalid_Id); + throw new ArgumentException(Resources.Services.HereGeocoding.Invalid_Id, nameof(parameters.Id)); } query = query.Add("id", parameters.Id); @@ -421,9 +409,8 @@ internal void AddBoundingParameters(AreaParameters parameters, ref QueryString q */ if ((!hasAt && !hasCircle && !hasBoundingBox) || (hasAt && (hasCircle || hasBoundingBox)) || (hasCircle && hasBoundingBox)) { - var error = _resourceStringProvider.GetString("Invalid Bounding Parameters"); - _logger.HereError(error); - throw new ArgumentException(error, nameof(parameters)); + _logger.HereError(Resources.Services.HereGeocoding.Invalid_Bounding_Parameters); + throw new ArgumentException(Resources.Services.HereGeocoding.Invalid_Bounding_Parameters, nameof(parameters)); } if (hasAt) @@ -432,7 +419,7 @@ internal void AddBoundingParameters(AreaParameters parameters, ref QueryString q } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid At Debug")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_At_Debug); } if (!string.IsNullOrWhiteSpace(parameters.InCountry)) @@ -441,7 +428,7 @@ internal void AddBoundingParameters(AreaParameters parameters, ref QueryString q } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid In Country")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_In_Country); } if (hasCircle) @@ -450,7 +437,7 @@ internal void AddBoundingParameters(AreaParameters parameters, ref QueryString q } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid In Circle")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_In_Circle); } if (hasBoundingBox) @@ -459,7 +446,7 @@ internal void AddBoundingParameters(AreaParameters parameters, ref QueryString q } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid In Bounding Box")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_In_Bounding_Box); } if (parameters.FlexiblePolyline != null) @@ -478,7 +465,7 @@ internal void AddBoundingParameters(AreaParameters parameters, ref QueryString q } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Route")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Route); } AddLimitingParameters(parameters, ref query); @@ -497,7 +484,7 @@ internal void AddLocatingParameters(BaseFilterParameters parameters, ref QuerySt } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid At Debug")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_At_Debug); } AddLimitingParameters(parameters, ref query); @@ -516,7 +503,7 @@ internal void AddLimitingParameters(BaseFilterParameters parameters, ref QuerySt } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Limit")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Limit); } AddBaseParameters(parameters, ref query); @@ -535,7 +522,7 @@ internal void AddBaseParameters(BaseParameters parameters, ref QueryString query } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Language")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Language); } if (!string.IsNullOrWhiteSpace(parameters.PoliticalView)) @@ -544,7 +531,7 @@ internal void AddBaseParameters(BaseParameters parameters, ref QueryString query } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Political View")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Political_View); } if (parameters.Show.Any()) @@ -553,7 +540,7 @@ internal void AddBaseParameters(BaseParameters parameters, ref QueryString query } else { - _logger.HereDebug(_resourceStringProvider.GetString("Invalid Show")); + _logger.HereDebug(Resources.Services.HereGeocoding.Invalid_Show); } } diff --git a/src/Geo.MapBox/Abstractions/IMapBoxGeocoding.cs b/src/Geo.MapBox/Abstractions/IMapBoxGeocoding.cs index 73bba80..22a5cf7 100644 --- a/src/Geo.MapBox/Abstractions/IMapBoxGeocoding.cs +++ b/src/Geo.MapBox/Abstractions/IMapBoxGeocoding.cs @@ -8,8 +8,8 @@ namespace Geo.MapBox.Abstractions using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; + using Geo.Core.Models.Exceptions; using Geo.MapBox.Models; - using Geo.MapBox.Models.Exceptions; using Geo.MapBox.Models.Parameters; using Geo.MapBox.Models.Responses; @@ -24,7 +24,7 @@ public interface IMapBoxGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with a of with the response from MapBox. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task>> GeocodingAsync(GeocodingParameters parameters, CancellationToken cancellationToken = default); /// @@ -33,7 +33,7 @@ public interface IMapBoxGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from MapBox. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task> ReverseGeocodingAsync(ReverseGeocodingParameters parameters, CancellationToken cancellationToken = default); } } diff --git a/src/Geo.MapBox/Converters/ContextConverter.cs b/src/Geo.MapBox/Converters/ContextConverter.cs index 7d5b2f0..b56291e 100644 --- a/src/Geo.MapBox/Converters/ContextConverter.cs +++ b/src/Geo.MapBox/Converters/ContextConverter.cs @@ -16,7 +16,7 @@ namespace Geo.MapBox.Converters using Geo.MapBox.Models.Responses; /// - /// A converter for a to a . + /// A converter for a to a . /// public class ContextConverter : JsonConverter { diff --git a/src/Geo.MapBox/DependencyInjection/ServiceCollectionExtensions.cs b/src/Geo.MapBox/DependencyInjection/ServiceCollectionExtensions.cs index cd60f06..6bc04fe 100644 --- a/src/Geo.MapBox/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Geo.MapBox/DependencyInjection/ServiceCollectionExtensions.cs @@ -7,7 +7,6 @@ namespace Geo.MapBox.DependencyInjection { using System; using System.Net.Http; - using Geo.Core.DependencyInjection; using Geo.MapBox.Abstractions; using Geo.MapBox.Models; using Geo.MapBox.Services; @@ -37,8 +36,6 @@ public static IHttpClientBuilder AddMapBoxServices( Action optionsBuilder, Action configureClient = null) { - services.AddCoreServices(); - if (optionsBuilder != null) { var options = new MapBoxOptionsBuilder(); diff --git a/src/Geo.MapBox/Geo.MapBox.csproj b/src/Geo.MapBox/Geo.MapBox.csproj index fc51053..abf7264 100644 --- a/src/Geo.MapBox/Geo.MapBox.csproj +++ b/src/Geo.MapBox/Geo.MapBox.csproj @@ -10,6 +10,7 @@ MIT https://github.com/JustinCanton/Geo.NET true + README.md @@ -33,4 +34,11 @@ + + + True + \ + + + diff --git a/src/Geo.MapBox/Models/Exceptions/MapBoxException.cs b/src/Geo.MapBox/Models/Exceptions/MapBoxException.cs deleted file mode 100644 index 7dd9a1e..0000000 --- a/src/Geo.MapBox/Models/Exceptions/MapBoxException.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.MapBox.Models.Exceptions -{ - using System; - using System.Globalization; - using System.Net.Http; - using System.Text.Json; - using System.Threading.Tasks; - using Geo.Core.Models.Exceptions; - - /// - /// A wrapper exception for any exceptions thrown in the MapBox functionality. The current exceptions wrapped by this exception are listed. - /// - /// Thrown when the parameter object is null or the request uri is null. - /// Thrown when the required parameter for the Google request is null or invalid. - /// - /// Thrown when the request failed due to an underlying issue such as network connectivity, - /// DNS failure, server certificate validation or timeout. - /// - /// Thrown when the MapBox request is cancelled. - /// Thrown when when an error occurs during JSON deserialization. - public sealed class MapBoxException : GeoCoreException - { - private const string DefaultMessage = "{0} See the inner exception for more information."; - - /// - /// Initializes a new instance of the class. - /// - public MapBoxException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public MapBoxException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - /// The exception that is the cause of the current exception. - public MapBoxException(string message, Exception inner) - : base(string.Format(CultureInfo.InvariantCulture, DefaultMessage, message), inner) - { - } - } -} diff --git a/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.Designer.cs b/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.Designer.cs index cf40ab9..2b03031 100644 --- a/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.Designer.cs +++ b/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.Designer.cs @@ -105,6 +105,15 @@ internal static string Invalid_Languages { } } + /// + /// Looks up a localized string similar to The limit is invalid and will not be used.. + /// + internal static string Invalid_Limit { + get { + return ResourceManager.GetString("Invalid Limit", resourceCulture); + } + } + /// /// Looks up a localized string similar to The proximity is invalid and will not be used.. /// diff --git a/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.en.resx b/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.en.resx index d4bcf01..60bab8d 100644 --- a/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.en.resx +++ b/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.en.resx @@ -132,6 +132,9 @@ The languages are invalid and will not be used. + + + The proximity is invalid and will not be used. diff --git a/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.resx b/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.resx index d4bcf01..ba4e506 100644 --- a/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.resx +++ b/src/Geo.MapBox/Resources/Services/MapBoxGeocoding.resx @@ -132,6 +132,9 @@ The languages are invalid and will not be used. + + The limit is invalid and will not be used. + The proximity is invalid and will not be used. diff --git a/src/Geo.MapBox/Services/MapBoxGeocoding.cs b/src/Geo.MapBox/Services/MapBoxGeocoding.cs index 7e987d9..74e7703 100644 --- a/src/Geo.MapBox/Services/MapBoxGeocoding.cs +++ b/src/Geo.MapBox/Services/MapBoxGeocoding.cs @@ -15,10 +15,10 @@ namespace Geo.MapBox.Services using System.Threading.Tasks; using Geo.Core; using Geo.Core.Extensions; + using Geo.Core.Models.Exceptions; using Geo.MapBox.Abstractions; using Geo.MapBox.Enums; using Geo.MapBox.Models; - using Geo.MapBox.Models.Exceptions; using Geo.MapBox.Models.Parameters; using Geo.MapBox.Models.Responses; using Microsoft.Extensions.Logging; @@ -27,16 +27,14 @@ namespace Geo.MapBox.Services /// /// A service to call the MapBox geocoding API. /// - public class MapBoxGeocoding : ClientExecutor, IMapBoxGeocoding + public class MapBoxGeocoding : GeoClient, IMapBoxGeocoding { - private const string ApiName = "MapBox"; private const string GeocodeUri = "https://api.mapbox.com/geocoding/v5/{0}/{1}.json"; private const string ReverseGeocodeUri = "https://api.mapbox.com/geocoding/v5/{0}/{1}.json"; private const string PlacesEndpoint = "mapbox.places"; private const string PermanentEndpoint = "mapbox.places-permanent"; private readonly IMapBoxKeyContainer _keyContainer; - private readonly IGeoNETResourceStringProvider _resourceStringProvider; private readonly ILogger _logger; /// @@ -44,22 +42,20 @@ public class MapBoxGeocoding : ClientExecutor, IMapBoxGeocoding /// /// A used for placing calls to the here Geocoding API. /// An used for fetching the here key. - /// An used to provide exceptions based on an exception type. - /// An used to create a resource string provider for log or exception messages. /// An used to create a logger used for logging information. public MapBoxGeocoding( HttpClient client, IMapBoxKeyContainer keyContainer, - IGeoNETExceptionProvider exceptionProvider, - IGeoNETResourceStringProviderFactory resourceStringProviderFactory, ILoggerFactory loggerFactory = null) - : base(client, exceptionProvider, resourceStringProviderFactory, loggerFactory) + : base(client, loggerFactory) { _keyContainer = keyContainer ?? throw new ArgumentNullException(nameof(keyContainer)); - _resourceStringProvider = resourceStringProviderFactory?.CreateResourceStringProvider() ?? throw new ArgumentNullException(nameof(resourceStringProviderFactory)); _logger = loggerFactory?.CreateLogger() ?? NullLogger.Instance; } + /// + protected override string ApiName => "MapBox"; + /// public async Task>> GeocodingAsync( GeocodingParameters parameters, @@ -67,7 +63,7 @@ public async Task>> GeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildGeocodingRequest); - return await CallAsync>, MapBoxException>(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync>>(uri, cancellationToken).ConfigureAwait(false); } /// @@ -77,7 +73,7 @@ public async Task> ReverseGeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildReverseGeocodingRequest); - return await CallAsync, MapBoxException>(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync>(uri, cancellationToken).ConfigureAwait(false); } /// @@ -92,9 +88,8 @@ internal Uri ValidateAndBuildUri(TParameters parameters, Func(TParameters parameters, Func 0) @@ -215,7 +207,7 @@ internal void AddBaseParameters(BaseParameters parameters, ref QueryString query } else { - _logger.MapBoxDebug(_resourceStringProvider.GetString("Invalid Languages")); + _logger.MapBoxDebug(Resources.Services.MapBoxGeocoding.Invalid_Languages); } if (parameters.Limit > 0 && parameters.Limit < 6) @@ -224,7 +216,7 @@ internal void AddBaseParameters(BaseParameters parameters, ref QueryString query } else { - _logger.MapBoxDebug(_resourceStringProvider.GetString("Invalid Languages")); + _logger.MapBoxDebug(Resources.Services.MapBoxGeocoding.Invalid_Limit); } #pragma warning disable CA1308 // Normalize strings to uppercase @@ -239,7 +231,7 @@ internal void AddBaseParameters(BaseParameters parameters, ref QueryString query } else { - _logger.MapBoxDebug(_resourceStringProvider.GetString("Invalid Types")); + _logger.MapBoxDebug(Resources.Services.MapBoxGeocoding.Invalid_Types); } if (!string.IsNullOrWhiteSpace(parameters.Worldview)) @@ -248,7 +240,7 @@ internal void AddBaseParameters(BaseParameters parameters, ref QueryString query } else { - _logger.MapBoxDebug(_resourceStringProvider.GetString("Invalid Worldview")); + _logger.MapBoxDebug(Resources.Services.MapBoxGeocoding.Invalid_Worldview); } } diff --git a/src/Geo.MapQuest/Abstractions/IMapQuestGeocoding.cs b/src/Geo.MapQuest/Abstractions/IMapQuestGeocoding.cs index 5c524a2..b1abb6d 100644 --- a/src/Geo.MapQuest/Abstractions/IMapQuestGeocoding.cs +++ b/src/Geo.MapQuest/Abstractions/IMapQuestGeocoding.cs @@ -7,7 +7,7 @@ namespace Geo.MapQuest.Abstractions { using System.Threading; using System.Threading.Tasks; - using Geo.MapQuest.Models.Exceptions; + using Geo.Core.Models.Exceptions; using Geo.MapQuest.Models.Parameters; using Geo.MapQuest.Models.Responses; @@ -22,7 +22,7 @@ public interface IMapQuestGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from MapQuest. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task> GeocodingAsync(GeocodingParameters parameters, CancellationToken cancellationToken = default); /// @@ -31,7 +31,7 @@ public interface IMapQuestGeocoding /// A with the parameters of the request. /// A used to cancel the request. /// A with the response from MapQuest. - /// Thrown for multiple different reasons. Check the inner exception for more information. + /// Thrown for multiple different reasons. Check the inner exception for more information. Task> ReverseGeocodingAsync(ReverseGeocodingParameters parameters, CancellationToken cancellationToken = default); } } diff --git a/src/Geo.MapQuest/DependencyInjection/ServiceCollectionExtensions.cs b/src/Geo.MapQuest/DependencyInjection/ServiceCollectionExtensions.cs index ac5ed02..ca90727 100644 --- a/src/Geo.MapQuest/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Geo.MapQuest/DependencyInjection/ServiceCollectionExtensions.cs @@ -7,7 +7,6 @@ namespace Geo.MapQuest.DependencyInjection { using System; using System.Net.Http; - using Geo.Core.DependencyInjection; using Geo.MapQuest.Abstractions; using Geo.MapQuest.Models; using Geo.MapQuest.Services; @@ -37,8 +36,6 @@ public static IHttpClientBuilder AddMapQuestServices( Action optionsBuilder, Action configureClient = null) { - services.AddCoreServices(); - if (optionsBuilder != null) { var options = new MapQuestOptionsBuilder(); diff --git a/src/Geo.MapQuest/Geo.MapQuest.csproj b/src/Geo.MapQuest/Geo.MapQuest.csproj index 1991c3d..817663a 100644 --- a/src/Geo.MapQuest/Geo.MapQuest.csproj +++ b/src/Geo.MapQuest/Geo.MapQuest.csproj @@ -10,6 +10,7 @@ MIT https://github.com/JustinCanton/Geo.NET true + README.md @@ -33,4 +34,11 @@ + + + True + \ + + + diff --git a/src/Geo.MapQuest/Models/Exceptions/MapQuestException.cs b/src/Geo.MapQuest/Models/Exceptions/MapQuestException.cs deleted file mode 100644 index c642734..0000000 --- a/src/Geo.MapQuest/Models/Exceptions/MapQuestException.cs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.MapQuest.Models.Exceptions -{ - using System; - using System.Globalization; - using System.Net.Http; - using System.Text.Json; - using System.Threading.Tasks; - using Geo.Core.Models.Exceptions; - - /// - /// A wrapper exception for any exceptions thrown in the MapQuest functionality. The current exceptions wrapped by this exception are listed. - /// - /// Thrown when the parameter object is null or the request uri is null. - /// Thrown when the required parameter for the Google request is null or invalid. - /// - /// Thrown when the request failed due to an underlying issue such as network connectivity, - /// DNS failure, server certificate validation or timeout. - /// - /// Thrown when the MapQuest request is cancelled. - /// Thrown when when an error occurs during JSON deserialization. - public sealed class MapQuestException : GeoCoreException - { - private const string DefaultMessage = "{0} See the inner exception for more information."; - - /// - /// Initializes a new instance of the class. - /// - public MapQuestException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public MapQuestException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - /// The exception that is the cause of the current exception. - public MapQuestException(string message, Exception inner) - : base(string.Format(CultureInfo.InvariantCulture, DefaultMessage, message), inner) - { - } - } -} diff --git a/src/Geo.MapQuest/Services/MapQuestGeocoding.cs b/src/Geo.MapQuest/Services/MapQuestGeocoding.cs index 08843bc..daa6b22 100644 --- a/src/Geo.MapQuest/Services/MapQuestGeocoding.cs +++ b/src/Geo.MapQuest/Services/MapQuestGeocoding.cs @@ -12,9 +12,9 @@ namespace Geo.MapQuest.Services using System.Threading.Tasks; using Geo.Core; using Geo.Core.Extensions; + using Geo.Core.Models.Exceptions; using Geo.MapQuest.Abstractions; using Geo.MapQuest.Enums; - using Geo.MapQuest.Models.Exceptions; using Geo.MapQuest.Models.Parameters; using Geo.MapQuest.Models.Responses; using Microsoft.Extensions.Logging; @@ -23,9 +23,8 @@ namespace Geo.MapQuest.Services /// /// A service to call the MapQuest geocoding API. /// - public class MapQuestGeocoding : ClientExecutor, IMapQuestGeocoding + public class MapQuestGeocoding : GeoClient, IMapQuestGeocoding { - private const string ApiName = "MapQuest"; private const string OpenGeocodeUri = "http://open.mapquestapi.com/geocoding/v1/address"; private const string OpenReverseGeocodeUri = "http://open.mapquestapi.com/geocoding/v1/reverse"; private const string GeocodeUri = "http://www.mapquestapi.com/geocoding/v1/address"; @@ -33,7 +32,6 @@ public class MapQuestGeocoding : ClientExecutor, IMapQuestGeocoding private readonly IMapQuestKeyContainer _keyContainer; private readonly IMapQuestEndpoint _endpoint; - private readonly IGeoNETResourceStringProvider _resourceStringProvider; private readonly ILogger _logger; /// @@ -42,24 +40,22 @@ public class MapQuestGeocoding : ClientExecutor, IMapQuestGeocoding /// A used for placing calls to the MapQuest Geocoding API. /// An used for fetching the MapQuest key. /// An used for fetching which MapQuest endpoint to use. - /// An used to provide exceptions based on an exception type. - /// An used to create a resource string provider for log or exception messages. /// An used to create a logger used for logging information. public MapQuestGeocoding( HttpClient client, IMapQuestKeyContainer keyContainer, IMapQuestEndpoint endpoint, - IGeoNETExceptionProvider exceptionProvider, - IGeoNETResourceStringProviderFactory resourceStringProviderFactory, ILoggerFactory loggerFactory = null) - : base(client, exceptionProvider, resourceStringProviderFactory, loggerFactory) + : base(client, loggerFactory) { _keyContainer = keyContainer ?? throw new ArgumentNullException(nameof(keyContainer)); _endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint)); - _resourceStringProvider = resourceStringProviderFactory?.CreateResourceStringProvider() ?? throw new ArgumentNullException(nameof(resourceStringProviderFactory)); _logger = loggerFactory?.CreateLogger() ?? NullLogger.Instance; } + /// + protected override string ApiName => "MapQuest"; + /// public async Task> GeocodingAsync( GeocodingParameters parameters, @@ -67,7 +63,7 @@ public async Task> GeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildGeocodingRequest); - return await CallAsync, MapQuestException>(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync>(uri, cancellationToken).ConfigureAwait(false); } /// @@ -77,7 +73,7 @@ public async Task> ReverseGeocodingAsync( { var uri = ValidateAndBuildUri(parameters, BuildReverseGeocodingRequest); - return await CallAsync, MapQuestException>(uri, ApiName, cancellationToken).ConfigureAwait(false); + return await GetAsync>(uri, cancellationToken).ConfigureAwait(false); } /// @@ -104,9 +100,8 @@ internal Uri ValidateAndBuildUri(TParameters parameters, Func(TParameters parameters, Func _mockTokenContainer; - private readonly IGeoNETExceptionProvider _exceptionProvider; - private readonly IGeoNETResourceStringProviderFactory _resourceStringProviderFactory; private readonly List _responseMessages = new List(); private bool _disposed; @@ -141,9 +139,7 @@ public ArcGISGeocodingShould() .ReturnsAsync(_responseMessages[_responseMessages.Count - 1]); var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" }); - _resourceStringProviderFactory = new GeoNETResourceStringProviderFactory(); _httpClient = new HttpClient(mockHandler.Object); - _exceptionProvider = new GeoNETExceptionProvider(); } /// @@ -643,7 +639,7 @@ protected virtual void Dispose(bool disposing) private ArcGISGeocoding BuildService() { - return new ArcGISGeocoding(_httpClient, _mockTokenContainer.Object, _exceptionProvider, _resourceStringProviderFactory); + return new ArcGISGeocoding(_httpClient, _mockTokenContainer.Object); } } } \ No newline at end of file diff --git a/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs b/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs index 9ff293e..f3752bf 100644 --- a/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs +++ b/test/Geo.Bing.Tests/Services/BingGeocodingShould.cs @@ -31,8 +31,6 @@ public class BingGeocodingShould : IDisposable { private readonly HttpClient _httpClient; private readonly BingKeyContainer _keyContainer; - private readonly IGeoNETExceptionProvider _exceptionProvider; - private readonly IGeoNETResourceStringProviderFactory _resourceStringProviderFactory; private readonly List _responseMessages = new List(); private bool _disposed; @@ -126,9 +124,7 @@ public BingGeocodingShould() .ReturnsAsync(_responseMessages[_responseMessages.Count - 1]); var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" }); - _resourceStringProviderFactory = new GeoNETResourceStringProviderFactory(); _httpClient = new HttpClient(mockHandler.Object); - _exceptionProvider = new GeoNETExceptionProvider(); } /// @@ -505,7 +501,7 @@ protected virtual void Dispose(bool disposing) private BingGeocoding BuildService() { - return new BingGeocoding(_httpClient, _keyContainer, _exceptionProvider, _resourceStringProviderFactory); + return new BingGeocoding(_httpClient, _keyContainer); } } } \ No newline at end of file diff --git a/test/Geo.Core.Tests/ClientExecutorShould.cs b/test/Geo.Core.Tests/GeoClientShould.cs similarity index 69% rename from test/Geo.Core.Tests/ClientExecutorShould.cs rename to test/Geo.Core.Tests/GeoClientShould.cs index d004628..3f67c93 100644 --- a/test/Geo.Core.Tests/ClientExecutorShould.cs +++ b/test/Geo.Core.Tests/GeoClientShould.cs @@ -1,4 +1,4 @@ -// +// // Copyright (c) Geo.NET. // Licensed under the MIT license. See the LICENSE file in the solution root for full license information. // @@ -13,7 +13,7 @@ namespace Geo.Core.Tests using System.Threading; using System.Threading.Tasks; using FluentAssertions; - using Geo.Core; + using Geo.Core.Models.Exceptions; using Geo.Core.Tests.Models; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; @@ -24,19 +24,17 @@ namespace Geo.Core.Tests /// /// Unit tests for the class. /// - public class ClientExecutorShould : IDisposable + public class GeoClientShould : IDisposable { private const string ApiName = "Test"; private readonly HttpClient _httpClient; - private readonly IGeoNETExceptionProvider _exceptionProvider; - private readonly IGeoNETResourceStringProviderFactory _resourceStringProviderFactory; private readonly List _responseMessages = new List(); private bool _disposed; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - public ClientExecutorShould() + public GeoClientShould() { var mockHandler = new Mock(); @@ -109,9 +107,7 @@ public ClientExecutorShould() .ReturnsAsync(_responseMessages[_responseMessages.Count - 1]); var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" }); - _resourceStringProviderFactory = new GeoNETResourceStringProviderFactory(); _httpClient = new HttpClient(mockHandler.Object); - _exceptionProvider = new GeoNETExceptionProvider(); } /// @@ -127,9 +123,9 @@ public void Dispose() [Fact] public void ThrowExceptionOnNullUri() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - sut.Invoking(x => x.CallAsync(new Uri("http://test.com/ArgumentNullException"))) + sut.Invoking(x => x.GetAsync(new Uri("http://test.com/ArgumentNullException"))) .Should() .ThrowAsync() .WithMessage("Value cannot be null. (Parameter 'requestUri')"); @@ -141,9 +137,9 @@ public void ThrowExceptionOnNullUri() [Fact] public void ThrowExceptionOnInvalidUri() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - sut.Invoking(x => x.CallAsync(new Uri("http://test.com/InvalidOperationException"))) + sut.Invoking(x => x.GetAsync(new Uri("http://test.com/InvalidOperationException"))) .Should() .ThrowAsync() .WithMessage("requestUri"); @@ -155,9 +151,9 @@ public void ThrowExceptionOnInvalidUri() [Fact] public void ThrowExceptionOnHttpFailure() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - sut.Invoking(x => x.CallAsync(new Uri("http://test.com/HttpRequestException"))) + sut.Invoking(x => x.GetAsync(new Uri("http://test.com/HttpRequestException"))) .Should() .ThrowAsync() .WithMessage("Exception of type 'System.Net.Http.HttpRequestException' was thrown."); @@ -169,9 +165,9 @@ public void ThrowExceptionOnHttpFailure() [Fact] public void ThrowExceptionOnCancelledRequest() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - sut.Invoking(x => x.CallAsync(new Uri("http://test.com/TaskCanceledException"))) + sut.Invoking(x => x.GetAsync(new Uri("http://test.com/TaskCanceledException"))) .Should() .ThrowAsync(); } @@ -182,9 +178,9 @@ public void ThrowExceptionOnCancelledRequest() [Fact] public void ThrowExceptionOnInvalidJson2() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - sut.Invoking(x => x.CallAsync(new Uri("http://test.com/JsonException"))) + sut.Invoking(x => x.GetAsync(new Uri("http://test.com/JsonException"))) .Should() .ThrowAsync(); } @@ -196,11 +192,13 @@ public void ThrowExceptionOnInvalidJson2() [Fact] public async Task ReturnsErrorJson() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); - var result = await sut.CallAsync(new Uri("http://test.com/Failure")); - result.IsSuccessful.Should().BeFalse(); - result.Result.Should().BeNull(); - result.Body.Should().Be("{'Message':'Access denied'}"); + var sut = new TestGeoClient(_httpClient); + + (await sut.Invoking(x => x.GetAsync(new Uri("http://test.com/Failure"))) + .Should() + .ThrowAsync()) + .WithMessage("The Test request failed.") + .And.Data["responseBody"].Should().Be("{'Message':'Access denied'}"); } /// @@ -210,11 +208,10 @@ public async Task ReturnsErrorJson() [Fact] public async Task SuccesfullyReturnObject() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - var result = await sut.CallAsync(new Uri("http://test.com/Success")); - result.IsSuccessful.Should().BeTrue(); - result.Result.TestField.Should().Be(1); + var result = await sut.GetAsync(new Uri("http://test.com/Success")); + result.TestField.Should().Be(1); } /// @@ -223,11 +220,11 @@ public async Task SuccesfullyReturnObject() [Fact] public async Task ThrowWrappedExceptionOnNullUri() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - (await sut.Invoking(x => x.CallAsync(new Uri("http://test.com/ArgumentNullException"), ApiName)) + (await sut.Invoking(x => x.GetAsync(new Uri("http://test.com/ArgumentNullException"))) .Should() - .ThrowAsync()) + .ThrowAsync()) .WithInnerException(); } @@ -237,11 +234,11 @@ public async Task ThrowWrappedExceptionOnNullUri() [Fact] public async Task ThrowWrappedExceptionOnInvalidUri() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - (await sut.Invoking(x => x.CallAsync(new Uri("http://test.com/InvalidOperationException"), ApiName)) + (await sut.Invoking(x => x.GetAsync(new Uri("http://test.com/InvalidOperationException"))) .Should() - .ThrowAsync()) + .ThrowAsync()) .WithInnerException(); } @@ -251,11 +248,11 @@ public async Task ThrowWrappedExceptionOnInvalidUri() [Fact] public async Task ThrowWrappedExceptionOnHttpFailure() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - (await sut.Invoking(x => x.CallAsync(new Uri("http://test.com/HttpRequestException"), ApiName)) + (await sut.Invoking(x => x.GetAsync(new Uri("http://test.com/HttpRequestException"))) .Should() - .ThrowAsync()) + .ThrowAsync()) .WithInnerException(); } @@ -265,11 +262,11 @@ public async Task ThrowWrappedExceptionOnHttpFailure() [Fact] public async Task ThrowWrappedExceptionOnCancelledRequest() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - (await sut.Invoking(x => x.CallAsync(new Uri("http://test.com/TaskCanceledException"), ApiName)) + (await sut.Invoking(x => x.GetAsync(new Uri("http://test.com/TaskCanceledException"))) .Should() - .ThrowAsync()) + .ThrowAsync()) .WithInnerException(); } @@ -279,11 +276,11 @@ public async Task ThrowWrappedExceptionOnCancelledRequest() [Fact] public async Task ThrowWrappedExceptionOnInvalidJson() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - (await sut.Invoking(x => x.CallAsync(new Uri("http://test.com/JsonException"), ApiName)) + (await sut.Invoking(x => x.GetAsync(new Uri("http://test.com/JsonException"))) .Should() - .ThrowAsync()) + .ThrowAsync()) .WithInnerException(); } @@ -293,11 +290,11 @@ public async Task ThrowWrappedExceptionOnInvalidJson() [Fact] public void ThrowWrappedExceptionOnErrorJson() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - sut.Invoking(x => x.CallAsync(new Uri("http://test.com/Failure"), ApiName)) + sut.Invoking(x => x.GetAsync(new Uri("http://test.com/Failure"))) .Should() - .ThrowAsync() + .ThrowAsync() .Where(x => x.Data.Count == 3 && x.Data["responseBody"].ToString() == "{'Message':'Access denied'}" && @@ -312,9 +309,9 @@ public void ThrowWrappedExceptionOnErrorJson() [Fact] public async Task SuccesfullyReturnOnlyObject() { - var sut = new TestClientExecutor(_httpClient, _exceptionProvider, _resourceStringProviderFactory); + var sut = new TestGeoClient(_httpClient); - var result = await sut.CallAsync(new Uri("http://test.com/Success"), ApiName); + var result = await sut.GetAsync(new Uri("http://test.com/Success")); result.TestField.Should().Be(1); } diff --git a/test/Geo.Core.Tests/GeoNETExceptionProviderTests.cs b/test/Geo.Core.Tests/GeoNETExceptionProviderTests.cs deleted file mode 100644 index 7f921fa..0000000 --- a/test/Geo.Core.Tests/GeoNETExceptionProviderTests.cs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core.Tests -{ - using System; - using FluentAssertions; - using Geo.Core.Tests.Models; - using Xunit; - - /// - /// Unit tests for the class. - /// - public class GeoNETExceptionProviderTests - { - [Fact] - public void GetException_WithoutInnerException_ReturnsException() - { - // Arrange - var sut = new GeoNETExceptionProvider(); - - // Act - var ex = sut.GetException("Test exception"); - - // Assert - ex.Message.Should().Be("Test exception"); - ex.InnerException.Should().BeNull(); - } - - [Fact] - public void GetException_WithInnerException_ReturnsException() - { - // Arrange - var sut = new GeoNETExceptionProvider(); - - // Act - var ex = sut.GetException("Test exception", new ArgumentNullException()); - - // Assert - ex.Message.Should().Be("Test exception"); - ex.InnerException.Should().NotBeNull(); - ex.InnerException.Should().BeOfType(); - } - } -} diff --git a/test/Geo.Core.Tests/Models/TestClass.cs b/test/Geo.Core.Tests/Models/TestClass.cs index eeab8d3..7ffd713 100644 --- a/test/Geo.Core.Tests/Models/TestClass.cs +++ b/test/Geo.Core.Tests/Models/TestClass.cs @@ -5,6 +5,8 @@ namespace Geo.Core.Tests.Models { + using System.Text.Json.Serialization; + /// /// A test data class used during testing. /// @@ -13,6 +15,7 @@ public class TestClass /// /// Gets or sets the test field. /// + [JsonPropertyName("TestField")] public int TestField { get; set; } } } diff --git a/test/Geo.Core.Tests/Models/TestClientExecutor.cs b/test/Geo.Core.Tests/Models/TestClientExecutor.cs deleted file mode 100644 index c4868e8..0000000 --- a/test/Geo.Core.Tests/Models/TestClientExecutor.cs +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core.Tests.Models -{ - using System.Net.Http; - using Geo.Core; - - /// - /// A test executor class for making http calls. - /// - public class TestClientExecutor : ClientExecutor - { - /// - /// Initializes a new instance of the class. - /// - /// A used for calls. - /// An used to provide exceptions based on an exception type. - /// An used to create a resource string provider for log or exception messages. - public TestClientExecutor( - HttpClient client, - IGeoNETExceptionProvider exceptionProvider, - IGeoNETResourceStringProviderFactory resourceStringProviderFactory) - : base(client, exceptionProvider, resourceStringProviderFactory) - { - } - } -} diff --git a/test/Geo.Core.Tests/Models/TestException.cs b/test/Geo.Core.Tests/Models/TestException.cs deleted file mode 100644 index 827fb87..0000000 --- a/test/Geo.Core.Tests/Models/TestException.cs +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) Geo.NET. -// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. -// - -namespace Geo.Core.Tests.Models -{ - using System; - using Geo.Core.Models.Exceptions; - - public sealed class TestException : GeoCoreException - { - /// - /// Initializes a new instance of the class. - /// - public TestException() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public TestException(string message) - : base(message) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - /// The exception that is the cause of the current exception. - public TestException(string message, Exception inner) - : base(message, inner) - { - } - } -} diff --git a/test/Geo.Core.Tests/Models/TestGeoClient.cs b/test/Geo.Core.Tests/Models/TestGeoClient.cs new file mode 100644 index 0000000..e239913 --- /dev/null +++ b/test/Geo.Core.Tests/Models/TestGeoClient.cs @@ -0,0 +1,28 @@ +// +// Copyright (c) Geo.NET. +// Licensed under the MIT license. See the LICENSE file in the solution root for full license information. +// + +namespace Geo.Core.Tests.Models +{ + using System.Net.Http; + using Geo.Core; + + /// + /// A test executor class for making http calls. + /// + public class TestGeoClient : GeoClient + { + /// + /// Initializes a new instance of the class. + /// + /// A used for calls. + public TestGeoClient( + HttpClient client) + : base(client) + { + } + + protected override string ApiName => "Test"; + } +} diff --git a/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs b/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs index ca1f0a4..84a366d 100644 --- a/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs +++ b/test/Geo.Google.Tests/Services/GoogleGeocodingShould.cs @@ -34,8 +34,6 @@ public class GoogleGeocodingShould : IDisposable { private readonly HttpClient _httpClient; private readonly GoogleKeyContainer _keyContainer; - private readonly IGeoNETExceptionProvider _exceptionProvider; - private readonly IGeoNETResourceStringProviderFactory _resourceStringProviderFactory; private readonly List _responseMessages = new List(); private bool _disposed; @@ -102,9 +100,7 @@ public GoogleGeocodingShould() .ReturnsAsync(_responseMessages[_responseMessages.Count - 1]); var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" }); - _resourceStringProviderFactory = new GeoNETResourceStringProviderFactory(); _httpClient = new HttpClient(mockHandler.Object); - _exceptionProvider = new GeoNETExceptionProvider(); } /// @@ -1037,7 +1033,7 @@ protected virtual void Dispose(bool disposing) private GoogleGeocoding BuildService() { - return new GoogleGeocoding(_httpClient, _keyContainer, _exceptionProvider, _resourceStringProviderFactory); + return new GoogleGeocoding(_httpClient, _keyContainer); } } } \ No newline at end of file diff --git a/test/Geo.Here.Tests/Services/HereGeocodingShould.cs b/test/Geo.Here.Tests/Services/HereGeocodingShould.cs index 057d1bf..842c4c6 100644 --- a/test/Geo.Here.Tests/Services/HereGeocodingShould.cs +++ b/test/Geo.Here.Tests/Services/HereGeocodingShould.cs @@ -15,8 +15,8 @@ namespace Geo.Here.Tests.Services using System.Web; using FluentAssertions; using Geo.Core; + using Geo.Core.Models.Exceptions; using Geo.Here.Models; - using Geo.Here.Models.Exceptions; using Geo.Here.Models.Parameters; using Geo.Here.Services; using Microsoft.Extensions.Localization; @@ -32,8 +32,6 @@ public class HereGeocodingShould : IDisposable { private readonly HttpClient _httpClient; private readonly HereKeyContainer _keyContainer; - private readonly IGeoNETExceptionProvider _exceptionProvider; - private readonly IGeoNETResourceStringProviderFactory _resourceStringProviderFactory; private readonly List _responseMessages = new List(); private bool _disposed; @@ -170,9 +168,7 @@ public HereGeocodingShould() .ReturnsAsync(_responseMessages[_responseMessages.Count - 1]); var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" }); - _resourceStringProviderFactory = new GeoNETResourceStringProviderFactory(); _httpClient = new HttpClient(mockHandler.Object); - _exceptionProvider = new GeoNETExceptionProvider(); } /// @@ -1109,7 +1105,7 @@ public void ValidateAndCraftUriFailsWithException1() Action act = () => sut.ValidateAndBuildUri(null, sut.BuildLookupRequest); act.Should() - .Throw() + .Throw() .WithMessage("*See the inner exception for more information.") .WithInnerException(); } @@ -1125,7 +1121,7 @@ public void ValidateAndCraftUriFailsWithException2() Action act = () => sut.ValidateAndBuildUri(new LookupParameters(), sut.BuildLookupRequest); act.Should() - .Throw() + .Throw() .WithMessage("*See the inner exception for more information.") .WithInnerException() #if NETCOREAPP3_1_OR_GREATER @@ -1317,7 +1313,7 @@ protected virtual void Dispose(bool disposing) private HereGeocoding BuildService() { - return new HereGeocoding(_httpClient, _keyContainer, _exceptionProvider, _resourceStringProviderFactory); + return new HereGeocoding(_httpClient, _keyContainer); } } } diff --git a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs index 788e156..3372d4b 100644 --- a/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs +++ b/test/Geo.MapBox.Tests/Services/MapBoxGeocodingShould.cs @@ -15,9 +15,9 @@ namespace Geo.MapBox.Tests.Services using System.Web; using FluentAssertions; using Geo.Core; + using Geo.Core.Models.Exceptions; using Geo.MapBox.Enums; using Geo.MapBox.Models; - using Geo.MapBox.Models.Exceptions; using Geo.MapBox.Models.Parameters; using Geo.MapBox.Services; using Microsoft.Extensions.Localization; @@ -33,8 +33,6 @@ public class MapBoxGeocodingShould : IDisposable { private readonly HttpClient _httpClient; private readonly MapBoxKeyContainer _keyContainer; - private readonly IGeoNETExceptionProvider _exceptionProvider; - private readonly IGeoNETResourceStringProviderFactory _resourceStringProviderFactory; private readonly List _responseMessages = new List(); private bool _disposed; @@ -91,9 +89,7 @@ public MapBoxGeocodingShould() .ReturnsAsync(_responseMessages[_responseMessages.Count - 1]); var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" }); - _resourceStringProviderFactory = new GeoNETResourceStringProviderFactory(); _httpClient = new HttpClient(mockHandler.Object); - _exceptionProvider = new GeoNETExceptionProvider(); } /// @@ -401,7 +397,7 @@ public void ValidateAndCraftUriFailsWithException1() Action act = () => sut.ValidateAndBuildUri(null, sut.BuildReverseGeocodingRequest); act.Should() - .Throw() + .Throw() .WithMessage("*See the inner exception for more information.") .WithInnerException(); } @@ -417,7 +413,7 @@ public void ValidateAndCraftUriFailsWithException2() Action act = () => sut.ValidateAndBuildUri(new ReverseGeocodingParameters(), sut.BuildReverseGeocodingRequest); act.Should() - .Throw() + .Throw() .WithMessage("*See the inner exception for more information.") .WithInnerException() #if NETCOREAPP3_1_OR_GREATER @@ -546,7 +542,7 @@ protected virtual void Dispose(bool disposing) private MapBoxGeocoding BuildService() { - return new MapBoxGeocoding(_httpClient, _keyContainer, _exceptionProvider, _resourceStringProviderFactory); + return new MapBoxGeocoding(_httpClient, _keyContainer); } } } \ No newline at end of file diff --git a/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs b/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs index 0537a04..d18a6ba 100644 --- a/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs +++ b/test/Geo.MapQuest.Tests/Services/MapQuestGeocodingShould.cs @@ -15,9 +15,9 @@ namespace Geo.MapQuest.Tests.Services using System.Web; using FluentAssertions; using Geo.Core; + using Geo.Core.Models.Exceptions; using Geo.MapQuest.Enums; using Geo.MapQuest.Models; - using Geo.MapQuest.Models.Exceptions; using Geo.MapQuest.Models.Parameters; using Geo.MapQuest.Services; using Microsoft.Extensions.Localization; @@ -34,8 +34,6 @@ public class MapQuestGeocodingShould : IDisposable private readonly HttpClient _httpClient; private readonly MapQuestKeyContainer _keyContainer; private readonly MapQuestEndpoint _endpoint; - private readonly IGeoNETExceptionProvider _exceptionProvider; - private readonly IGeoNETResourceStringProviderFactory _resourceStringProviderFactory; private readonly List _responseMessages = new List(); private bool _disposed; @@ -104,9 +102,7 @@ public MapQuestGeocodingShould() .ReturnsAsync(_responseMessages[_responseMessages.Count - 1]); var options = Options.Create(new LocalizationOptions { ResourcesPath = "Resources" }); - _resourceStringProviderFactory = new GeoNETResourceStringProviderFactory(); _httpClient = new HttpClient(mockHandler.Object); - _exceptionProvider = new GeoNETExceptionProvider(); } /// @@ -416,7 +412,7 @@ public void ValidateAndCraftUriFailsWithException1() Action act = () => sut.ValidateAndBuildUri(null, sut.BuildReverseGeocodingRequest); act.Should() - .Throw() + .Throw() .WithMessage("*See the inner exception for more information.") .WithInnerException(); } @@ -432,7 +428,7 @@ public void ValidateAndCraftUriFailsWithException2() Action act = () => sut.ValidateAndBuildUri(new ReverseGeocodingParameters(), sut.BuildReverseGeocodingRequest); act.Should() - .Throw() + .Throw() .WithMessage("*See the inner exception for more information.") .WithInnerException() #if NETCOREAPP3_1_OR_GREATER @@ -535,7 +531,7 @@ protected virtual void Dispose(bool disposing) private MapQuestGeocoding BuildService(MapQuestEndpoint endpoint = null) { - return new MapQuestGeocoding(_httpClient, _keyContainer, endpoint ?? _endpoint, _exceptionProvider, _resourceStringProviderFactory); + return new MapQuestGeocoding(_httpClient, _keyContainer, endpoint ?? _endpoint); } } } \ No newline at end of file