From d35b638c74cea5a78af0f949f250a783c0f63234 Mon Sep 17 00:00:00 2001 From: Developer 02 Date: Mon, 29 Jul 2024 13:04:36 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20Umbenennung=20und=20Konfiguration?= =?UTF-8?q?=20f=C3=BCr=20Legacy-Projekt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DigitalData.Core.Client.Legacy wurde in DigitalData.Core.Legacy.Client umbenannt. - Projektdateien von DigitalData.Core.Client wurden nach DigitalData.Core.Legacy.Client kopiert. - DigitalData.Core.Legacy.Client wurde für .NET Framework konfiguriert. --- .../BaseHttpClientService.cs | 74 +++++++++++++ .../DIExtensions.cs | 37 +++++++ ... => DigitalData.Core.Legacy.Client.csproj} | 34 +++++- .../HttpClientOptions.cs | 7 ++ .../HttpClientService.cs | 14 +++ .../HttpExtensions.cs | 103 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 4 +- .../ServiceFactory.cs | 26 +++++ DigitalData.Core.Client.Legacy/app.config | 11 ++ .../packages.config | 9 +- DigitalData.Core.sln | 2 +- 11 files changed, 315 insertions(+), 6 deletions(-) create mode 100644 DigitalData.Core.Client.Legacy/BaseHttpClientService.cs create mode 100644 DigitalData.Core.Client.Legacy/DIExtensions.cs rename DigitalData.Core.Client.Legacy/{DigitalData.Core.Client.Legacy.csproj => DigitalData.Core.Legacy.Client.csproj} (60%) create mode 100644 DigitalData.Core.Client.Legacy/HttpClientOptions.cs create mode 100644 DigitalData.Core.Client.Legacy/HttpClientService.cs create mode 100644 DigitalData.Core.Client.Legacy/HttpExtensions.cs create mode 100644 DigitalData.Core.Client.Legacy/ServiceFactory.cs create mode 100644 DigitalData.Core.Client.Legacy/app.config diff --git a/DigitalData.Core.Client.Legacy/BaseHttpClientService.cs b/DigitalData.Core.Client.Legacy/BaseHttpClientService.cs new file mode 100644 index 0000000..9a6dceb --- /dev/null +++ b/DigitalData.Core.Client.Legacy/BaseHttpClientService.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using System; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; + +namespace DigitalData.Core.Legacy.Client +{ + public class BaseHttpClientService + { + protected readonly HttpClient _client; + protected readonly CookieContainer _cookies; + + public string Uri { get; } + + public BaseHttpClientService(HttpClient client, CookieContainer cookieContainer, IOptions clientOptions) + { + _client = client; + _cookies = cookieContainer; + Uri = clientOptions.Value.Uri; + } + + public CookieCollection GetCookies(string route = "") => _cookies.GetCookies(uri: new Uri(Uri + route)); + + public async Task FetchAsync( + string route = "", + HttpMethod method = null, + HttpContent body = null, + Dictionary form = null, + bool sendWithCookie = true, + bool saveCookie = true + ) + { + // set default HTTP method as GET + if(method is null) + method = HttpMethod.Get; + + // create URL + var requestUriStr = Uri + route; + var requestUri = new Uri(requestUriStr); + + var requestMessage = new HttpRequestMessage(method, requestUriStr); + + // Add cookie to request + if (sendWithCookie) + { + var cookieHeader = _cookies.GetCookieHeader(requestUri); + if (!string.IsNullOrWhiteSpace(cookieHeader)) + { + requestMessage.Headers.Add("Cookie", cookieHeader); + } + } + + // Add body content if provided + if (body != null && form != null) + throw new InvalidOperationException("Body content and form data cannot both be set."); + else if (body != null) + requestMessage.Content = body; + else if (form != null) + requestMessage.Content = new FormUrlEncodedContent(form); + + var response = await _client.SendAsync(requestMessage); + + // Add response cookies to cookies + if (saveCookie) + if (response.Headers.TryGetValues("Set-Cookie", out var cookies)) + foreach (var cookie in cookies) + _cookies.SetCookies(requestUri, cookie); + + return response; + } + } +} \ No newline at end of file diff --git a/DigitalData.Core.Client.Legacy/DIExtensions.cs b/DigitalData.Core.Client.Legacy/DIExtensions.cs new file mode 100644 index 0000000..8f93ebf --- /dev/null +++ b/DigitalData.Core.Client.Legacy/DIExtensions.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using System; +using System.Net; +using System.Net.Http; + +namespace DigitalData.Core.Legacy.Client +{ + public static class DIExtensions + { + public static IServiceCollection AddHttpClientService(this IServiceCollection services, string uri) + { + services.TryAddSingleton(); + services.TryAddSingleton(); + services.AddSingleton(); + services.Configure(opt => opt.Uri = uri); + + return services; + } + + public static IServiceCollection AddHttpClientService(this IServiceCollection services, Action clientOptions = null, bool setAsDefaultBase = false) + where TClientOptions : HttpClientOptions + { + services.TryAddSingleton(); + services.TryAddSingleton(); + services.AddSingleton>(); + + if(clientOptions != null) + services.Configure(clientOptions); + + if (setAsDefaultBase) + services.AddSingleton>(); + + return services; + } + } +} \ No newline at end of file diff --git a/DigitalData.Core.Client.Legacy/DigitalData.Core.Client.Legacy.csproj b/DigitalData.Core.Client.Legacy/DigitalData.Core.Legacy.Client.csproj similarity index 60% rename from DigitalData.Core.Client.Legacy/DigitalData.Core.Client.Legacy.csproj rename to DigitalData.Core.Client.Legacy/DigitalData.Core.Legacy.Client.csproj index 20cf1e0..68d08f4 100644 --- a/DigitalData.Core.Client.Legacy/DigitalData.Core.Client.Legacy.csproj +++ b/DigitalData.Core.Client.Legacy/DigitalData.Core.Legacy.Client.csproj @@ -40,14 +40,37 @@ ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.8.0.0\lib\net462\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + ..\packages\Microsoft.Extensions.Options.8.0.2\lib\net462\Microsoft.Extensions.Options.dll + + + ..\packages\Microsoft.Extensions.Primitives.8.0.0\lib\net462\Microsoft.Extensions.Primitives.dll + + + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + ..\packages\System.ValueTuple.4.5.0\lib\net461\System.ValueTuple.dll + @@ -56,9 +79,16 @@ + + + + + + + diff --git a/DigitalData.Core.Client.Legacy/HttpClientOptions.cs b/DigitalData.Core.Client.Legacy/HttpClientOptions.cs new file mode 100644 index 0000000..9ccd9c1 --- /dev/null +++ b/DigitalData.Core.Client.Legacy/HttpClientOptions.cs @@ -0,0 +1,7 @@ +namespace DigitalData.Core.Legacy.Client +{ + public class HttpClientOptions + { + public string Uri { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/DigitalData.Core.Client.Legacy/HttpClientService.cs b/DigitalData.Core.Client.Legacy/HttpClientService.cs new file mode 100644 index 0000000..e2a723a --- /dev/null +++ b/DigitalData.Core.Client.Legacy/HttpClientService.cs @@ -0,0 +1,14 @@ +using Microsoft.Extensions.Options; +using System.Net; +using System.Net.Http; + +namespace DigitalData.Core.Legacy.Client +{ + public class HttpClientService : BaseHttpClientService + where TClientOptions : HttpClientOptions + { + public HttpClientService(HttpClient client, CookieContainer cookieContainer, IOptions clientOptions) : base(client, cookieContainer, clientOptions) + { + } + } +} \ No newline at end of file diff --git a/DigitalData.Core.Client.Legacy/HttpExtensions.cs b/DigitalData.Core.Client.Legacy/HttpExtensions.cs new file mode 100644 index 0000000..7293504 --- /dev/null +++ b/DigitalData.Core.Client.Legacy/HttpExtensions.cs @@ -0,0 +1,103 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; + +namespace DigitalData.Core.Legacy +{ + /// + /// Extension methods for HttpClient and HttpResponseMessage. + /// + public static class HttpExtensions + { + /// + /// Reads the content of the HTTP response message as a string. + /// + /// The HTTP response message. + /// A task representing the response content as a string. + public static async Task Text(this HttpResponseMessage response) => await response.Content.ReadAsStringAsync(); + + /// + /// Reads the content of the HTTP response message and deserializes it to a specified type. + /// + /// The type to deserialize the response content to. + /// The HTTP response message. + /// A task representing the deserialized response content. + public static async Task Json(this HttpResponseMessage response) => JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + + /// + /// Reads the content of the HTTP response message and deserializes it to a dynamic object. + /// + /// The HTTP response message. + /// A task representing the deserialized response content as a dynamic object. + public static async Task Json(this HttpResponseMessage response) + { + string json = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(json) ?? string.Empty; + } + + /// + /// Reads the content of the HTTP response message and deserializes it to a list of dynamic objects. + /// + /// The HTTP response message. + /// A task representing the deserialized response content as a list of dynamic objects. + public static async Task> JsonList(this HttpResponseMessage response) + { + string json = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(json) ?? string.Empty; + } + + /// + /// Executes an action when a task is completed. + /// + /// The type of the task result. + /// The task to await. + /// The action to execute when the task is completed. + public static async void ThenAsync(this Task task, Action toDo) + { + var then = await task; + toDo(then); + } + + /// + /// Executes a function when a task is completed and returns the result. + /// + /// The type of the task result. + /// The return type of the function. + /// The task to await. + /// The function to execute when the task is completed. + /// A task representing the result of the function. + public static async Task ThenAsync(this Task task, Func toDo) + { + var then = await task; + return toDo(then); + } + + /// + /// Executes an asynchronous function when a task is completed and returns the result. + /// + /// The type of the task result. + /// The return type of the asynchronous function. + /// The task to await. + /// The asynchronous function to execute when the task is completed. + /// A task representing the result of the asynchronous function. + public static async Task ThenAsync(this Task task, Func> toDoAsync) + { + var then = await task; + return await toDoAsync(then); + } + + /// + /// Executes an action for each element in an enumerable collection. + /// + /// The type of the elements in the collection. + /// The enumerable collection of elements. + /// The action to execute for each element. + public static void ForEach(this IEnumerable values, Action action) + { + foreach (var value in values) + action(value); + } + } +} \ No newline at end of file diff --git a/DigitalData.Core.Client.Legacy/Properties/AssemblyInfo.cs b/DigitalData.Core.Client.Legacy/Properties/AssemblyInfo.cs index 0ef194c..62ff96e 100644 --- a/DigitalData.Core.Client.Legacy/Properties/AssemblyInfo.cs +++ b/DigitalData.Core.Client.Legacy/Properties/AssemblyInfo.cs @@ -5,11 +5,11 @@ using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("DigitalData.Core.Client.Legacy")] +[assembly: AssemblyTitle("DigitalData.Core.Legacy.Client")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Digital Data GmbH")] -[assembly: AssemblyProduct("DigitalData.Core.Client.Legacy")] +[assembly: AssemblyProduct("DigitalData.Core.Legacy.Client")] [assembly: AssemblyCopyright("Copyright © Digital Data GmbH 2024")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/DigitalData.Core.Client.Legacy/ServiceFactory.cs b/DigitalData.Core.Client.Legacy/ServiceFactory.cs new file mode 100644 index 0000000..a7c1b2c --- /dev/null +++ b/DigitalData.Core.Client.Legacy/ServiceFactory.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.DependencyInjection; +using System; + +namespace DigitalData.Core.Legacy.Client +{ + public static class ServiceFactory + { + private static readonly IServiceCollection _services = new ServiceCollection(); + private static readonly Lazy _lazyProvider = new Lazy(Build); + + public static IServiceCollection Services => !_lazyProvider.IsValueCreated + ? _services + : throw new InvalidOperationException( + "Service provider has already been created. " + + "Further modifications to the service collection are not allowed. " + + "This is to ensure that the dependency injection container remains in a consistent state."); + + private static IServiceProvider Build() => _services.BuildServiceProvider(); + + public static T Provide() => _lazyProvider.Value.GetRequiredService(); + + public static HttpClientService ProvideHttpClientService() + where TOptions : HttpClientOptions + => _lazyProvider.Value.GetRequiredService>(); + } +} \ No newline at end of file diff --git a/DigitalData.Core.Client.Legacy/app.config b/DigitalData.Core.Client.Legacy/app.config new file mode 100644 index 0000000..1696df6 --- /dev/null +++ b/DigitalData.Core.Client.Legacy/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/DigitalData.Core.Client.Legacy/packages.config b/DigitalData.Core.Client.Legacy/packages.config index 41208c5..1e8af40 100644 --- a/DigitalData.Core.Client.Legacy/packages.config +++ b/DigitalData.Core.Client.Legacy/packages.config @@ -3,6 +3,13 @@ - + + + + + + + + \ No newline at end of file diff --git a/DigitalData.Core.sln b/DigitalData.Core.sln index 5e72536..00b72c9 100644 --- a/DigitalData.Core.sln +++ b/DigitalData.Core.sln @@ -17,7 +17,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.Core.Client", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.Core.Abstractions", "DigitalData.Core.Abstractions\DigitalData.Core.Abstractions.csproj", "{13E40DF1-6123-4838-9BF8-086C94E6ADF6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalData.Core.Client.Legacy", "DigitalData.Core.Client.Legacy\DigitalData.Core.Client.Legacy.csproj", "{E009A053-A9F4-48F2-984F-EF5C376A9B14}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalData.Core.Legacy.Client", "DigitalData.Core.Client.Legacy\DigitalData.Core.Legacy.Client.csproj", "{E009A053-A9F4-48F2-984F-EF5C376A9B14}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution