Compare commits
10 Commits
71368e5c85
...
9628b46ba0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9628b46ba0 | ||
|
|
1f8142852e | ||
|
|
bdd78be66c | ||
|
|
470902911e | ||
|
|
3f7ebdb632 | ||
|
|
23ef1a5797 | ||
|
|
4a7f2a41fa | ||
|
|
5f9e716ca6 | ||
|
|
91c8b98f44 | ||
|
|
10fc56b262 |
5
ReC.sln
5
ReC.sln
@ -15,6 +15,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReC.Application", "src\ReC.
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReC.Client", "src\ReC.Client\ReC.Client.csproj", "{DA3A6BDD-8045-478F-860B-D1F0EB97F02B}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReC.Client", "src\ReC.Client\ReC.Client.csproj", "{DA3A6BDD-8045-478F-860B-D1F0EB97F02B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
assets\icon.png = assets\icon.png
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|||||||
BIN
assets/icon.png
Normal file
BIN
assets/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
@ -6,18 +6,35 @@ using System.Net.Http;
|
|||||||
|
|
||||||
namespace ReC.Client
|
namespace ReC.Client
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides extension methods for setting up the ReC client in an <see cref="IServiceCollection"/>.
|
||||||
|
/// </summary>
|
||||||
public static class DependencyInjection
|
public static class DependencyInjection
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Adds and configures the <see cref="HttpClient"/> for the <see cref="ReCClient"/> to the specified <see cref="IServiceCollection"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
|
||||||
|
/// <param name="apiUri">The base URI of the ReC API.</param>
|
||||||
|
/// <returns>An <see cref="IHttpClientBuilder"/> that can be used to configure the client.</returns>
|
||||||
public static IHttpClientBuilder AddRecClient(this IServiceCollection services, string apiUri)
|
public static IHttpClientBuilder AddRecClient(this IServiceCollection services, string apiUri)
|
||||||
{
|
{
|
||||||
|
services.AddScoped<ReCClient>();
|
||||||
return services.AddHttpClient(ReCClient.ClientName, client =>
|
return services.AddHttpClient(ReCClient.ClientName, client =>
|
||||||
{
|
{
|
||||||
client.BaseAddress = new Uri(apiUri);
|
client.BaseAddress = new Uri(apiUri);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds and configures the <see cref="HttpClient"/> for the <see cref="ReCClient"/> to the specified <see cref="IServiceCollection"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">The <see cref="IServiceCollection"/> to add the services to.</param>
|
||||||
|
/// <param name="configureClient">An action to configure the <see cref="HttpClient"/>.</param>
|
||||||
|
/// <returns>An <see cref="IHttpClientBuilder"/> that can be used to configure the client.</returns>
|
||||||
public static IHttpClientBuilder AddRecClient(this IServiceCollection services, Action<HttpClient> configureClient)
|
public static IHttpClientBuilder AddRecClient(this IServiceCollection services, Action<HttpClient> configureClient)
|
||||||
{
|
{
|
||||||
|
services.AddScoped<ReCClient>();
|
||||||
return services.AddHttpClient(ReCClient.ClientName, configureClient);
|
return services.AddHttpClient(ReCClient.ClientName, configureClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,19 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net462;net8.0</TargetFrameworks>
|
<TargetFrameworks>net462;net8.0</TargetFrameworks>
|
||||||
|
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(MSBuildProjectName).xml</DocumentationFile>
|
||||||
|
<PackageId>ReC.Client</PackageId>
|
||||||
|
<Authors>Digital Data GmbH</Authors>
|
||||||
|
<Company>Digital Data GmbH</Company>
|
||||||
|
<Product>ReC.Client</Product>
|
||||||
|
<Copyright>Copyright 2025</Copyright>
|
||||||
|
<PackageIcon>icon.png</PackageIcon>
|
||||||
|
<RepositoryUrl>http://git.dd:3000/AppStd/Rec.git</RepositoryUrl>
|
||||||
|
<PackageTags>digital data rec api</PackageTags>
|
||||||
|
<Version>1.0.0-beta</Version>
|
||||||
|
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||||
|
<FileVersion>1.0.0.0</FileVersion>
|
||||||
|
<Description>Client-Bibliothek für die Interaktion mit der ReC.API, die typisierten HTTP-Zugriff und DI-Integration bietet.</Description>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(TargetFramework)' != 'net462'">
|
<PropertyGroup Condition="'$(TargetFramework)' != 'net462'">
|
||||||
@ -10,8 +23,15 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="10.0.0" />
|
<None Include="..\..\assets\icon.png">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||||
<PackageReference Include="System.Text.Json" Version="9.0.11" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System.Text.Json;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
#if NETFRAMEWORK
|
#if NETFRAMEWORK
|
||||||
using System;
|
using System;
|
||||||
@ -10,23 +9,36 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace ReC.Client
|
namespace ReC.Client
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A client for interacting with the ReC API.
|
||||||
|
/// </summary>
|
||||||
public class ReCClient
|
public class ReCClient
|
||||||
{
|
{
|
||||||
private readonly HttpClient _http;
|
private readonly HttpClient _http;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A unique name for the HttpClient used by the ReCClient.
|
||||||
|
/// </summary>
|
||||||
public static readonly string ClientName = Guid.NewGuid().ToString();
|
public static readonly string ClientName = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ReCClient"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="httpClientFactory">The factory to create HttpClients.</param>
|
||||||
public ReCClient(IHttpClientFactory httpClientFactory)
|
public ReCClient(IHttpClientFactory httpClientFactory)
|
||||||
{
|
{
|
||||||
_http = httpClientFactory.CreateClient(ClientName);
|
_http = httpClientFactory.CreateClient(ClientName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// POST api/RecAction/invoke/{profileId}
|
/// Asynchronously invokes a ReC action for a specific profile.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="profileId"></param>
|
/// <remarks>
|
||||||
/// <param name="cancellationToken"></param>
|
/// This method sends a POST request to the <c>api/RecAction/invoke/{profileId}</c> endpoint.
|
||||||
/// <returns>True if the request was successful, false otherwise</returns>
|
/// </remarks>
|
||||||
|
/// <param name="profileId">The ID of the profile to invoke the action for.</param>
|
||||||
|
/// <param name="cancellationToken">A token to cancel the asynchronous operation.</param>
|
||||||
|
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous operation. The task result is <see langword="true"/> if the request was successful; otherwise, <see langword="false"/>.</returns>
|
||||||
public async Task<bool> InvokeRecActionAsync(int profileId, CancellationToken cancellationToken = default)
|
public async Task<bool> InvokeRecActionAsync(int profileId, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var resp = await _http.PostAsync($"api/RecAction/invoke/{profileId}", content: null, cancellationToken);
|
var resp = await _http.PostAsync($"api/RecAction/invoke/{profileId}", content: null, cancellationToken);
|
||||||
@ -34,10 +46,14 @@ namespace ReC.Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// POST api/RecAction/invoke/{profileId} (Synchronous version)
|
/// Synchronously invokes a ReC action for a specific profile.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="profileId"></param>
|
/// <remarks>
|
||||||
/// <returns>True if the request was successful, false otherwise</returns>
|
/// This method sends a POST request to the <c>api/RecAction/invoke/{profileId}</c> endpoint.
|
||||||
|
/// This is the synchronous version of <see cref="InvokeRecActionAsync(int, CancellationToken)"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="profileId">The ID of the profile to invoke the action for.</param>
|
||||||
|
/// <returns><see langword="true"/> if the request was successful; otherwise, <see langword="false"/>.</returns>
|
||||||
[Obsolete("Use InvokeRecActionAsync instead to avoid potential deadlocks and improve performance.")]
|
[Obsolete("Use InvokeRecActionAsync instead to avoid potential deadlocks and improve performance.")]
|
||||||
public bool InvokeRecAction(int profileId)
|
public bool InvokeRecAction(int profileId)
|
||||||
{
|
{
|
||||||
@ -49,33 +65,59 @@ namespace ReC.Client
|
|||||||
private static readonly IServiceCollection Services = new ServiceCollection();
|
private static readonly IServiceCollection Services = new ServiceCollection();
|
||||||
|
|
||||||
#if NET8_0_OR_GREATER
|
#if NET8_0_OR_GREATER
|
||||||
private static IServiceProvider? ServiceProvider = null;
|
private static IServiceProvider? Provider = null;
|
||||||
#else
|
#else
|
||||||
private static IServiceProvider ServiceProvider = null;
|
private static IServiceProvider Provider = null;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configures and builds the static <see cref="IServiceProvider"/> for creating <see cref="ReCClient"/> instances.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method should only be called once during application startup.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="apiUri">The base URI of the ReC API.</param>
|
||||||
|
/// <exception cref="InvalidOperationException">Thrown if the static provider has already been built.</exception>
|
||||||
|
[Obsolete("Use a local service collection instead of the static provider.")]
|
||||||
public static void BuildStaticClient(string apiUri)
|
public static void BuildStaticClient(string apiUri)
|
||||||
{
|
{
|
||||||
if(ServiceProvider != null)
|
if(Provider != null)
|
||||||
throw new InvalidOperationException("Static ServiceProvider is already built.");
|
throw new InvalidOperationException("Static Provider is already built.");
|
||||||
|
|
||||||
Services.AddHttpClient(ClientName, client =>
|
Services.AddRecClient(apiUri);
|
||||||
{
|
Provider = Services.BuildServiceProvider();
|
||||||
client.BaseAddress = new Uri(apiUri);
|
|
||||||
});
|
|
||||||
ServiceProvider = Services.BuildServiceProvider();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ReCClient Static
|
/// <summary>
|
||||||
|
/// Configures and builds the static <see cref="IServiceProvider"/> for creating <see cref="ReCClient"/> instances.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method should only be called once during application startup.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="configureClient">An action to configure the <see cref="HttpClient"/>.</param>
|
||||||
|
/// <exception cref="InvalidOperationException">Thrown if the static provider has already been built.</exception>
|
||||||
|
[Obsolete("Use a local service collection instead of the static provider.")]
|
||||||
|
public static void BuildStaticClient(Action<HttpClient> configureClient)
|
||||||
{
|
{
|
||||||
get
|
if (Provider != null)
|
||||||
{
|
throw new InvalidOperationException("Static Provider is already built.");
|
||||||
if (ServiceProvider == null)
|
|
||||||
throw new InvalidOperationException("Static ServiceProvider is not built. Call BuildStaticClient first.");
|
|
||||||
|
|
||||||
var httpClientFactory = ServiceProvider.GetRequiredService<IHttpClientFactory>();
|
Services.AddRecClient(configureClient);
|
||||||
return new ReCClient(httpClientFactory);
|
Provider = Services.BuildServiceProvider();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="ReCClient"/> instance using the statically configured provider.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A new instance of the <see cref="ReCClient"/>.</returns>
|
||||||
|
/// <exception cref="InvalidOperationException">Thrown if <see cref="BuildStaticClient(string)"/> has not been called yet.</exception>
|
||||||
|
[Obsolete("Use a local service collection instead of the static provider.")]
|
||||||
|
public static ReCClient Create()
|
||||||
|
{
|
||||||
|
if (Provider == null)
|
||||||
|
throw new InvalidOperationException("Static Provider is not built. Call BuildStaticClient first.");
|
||||||
|
|
||||||
|
return Provider.GetRequiredService<ReCClient>();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user