Compare commits
176 Commits
d937383c78
...
feat/clien
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
988d1e2b16 | ||
|
|
4e0e907313 | ||
|
|
0bfec426d4 | ||
|
|
08ffe821ff | ||
|
|
fa5d0f1b26 | ||
|
|
38bd23d012 | ||
|
|
50e2581727 | ||
|
|
5c09d7775b | ||
|
|
dbfee49dee | ||
|
|
0c6c84852d | ||
|
|
3f61b5064c | ||
|
|
f79d2e2352 | ||
|
|
201da81aa5 | ||
|
|
bea57a25e8 | ||
|
|
0ff89b4906 | ||
|
|
600d17ef40 | ||
|
|
16565eca4d | ||
|
|
8787c04917 | ||
|
|
b3568216a0 | ||
|
|
6f520732dd | ||
|
|
8003cffb9b | ||
|
|
b02f93b38d | ||
|
|
2f0c6a905a | ||
|
|
baf1f5e045 | ||
|
|
b8a4a1f2b5 | ||
|
|
a69f610ef4 | ||
|
|
016d8bdcf2 | ||
|
|
738005f5dc | ||
|
|
c96af25e23 | ||
|
|
35e2fef046 | ||
|
|
b8fb45d4a3 | ||
|
|
fa60147507 | ||
|
|
e9d408a717 | ||
|
|
5fd3fa2fc6 | ||
|
|
0d5bcedc01 | ||
|
|
2e68a37944 | ||
|
|
8076efb934 | ||
|
|
c38f7dcf72 | ||
|
|
6e4942c885 | ||
|
|
d0dfd834b0 | ||
|
|
aa9951f242 | ||
|
|
506685a0b5 | ||
|
|
c9548238bb | ||
|
|
3ffdd49a47 | ||
|
|
609cd29dc5 | ||
|
|
cc3d1f58d3 | ||
|
|
c03f39c1a9 | ||
|
|
750f7bc20c | ||
|
|
65989b23b3 | ||
|
|
c895d2df0e | ||
|
|
0c451cb834 | ||
|
|
9396f48f46 | ||
|
|
1a941b4728 | ||
|
|
c6942164e2 | ||
|
|
343560ed62 | ||
|
|
6873bac8a1 | ||
|
|
09406ca505 | ||
|
|
3aa5ad782f | ||
|
|
5991444efd | ||
|
|
f720ea9cd6 | ||
|
|
a4b96c2f3e | ||
|
|
816d5835f1 | ||
|
|
4a64a31d47 | ||
|
|
e9b2ba788f | ||
|
|
e53813500a | ||
|
|
25e3855de2 | ||
|
|
dd3d6e70cc | ||
|
|
02a87309df | ||
|
|
0f7bdc9d0e | ||
|
|
f9df2fb29e | ||
|
|
ef7da0e52c | ||
|
|
f602a842be | ||
|
|
52a7664e57 | ||
|
|
ea3d1312b8 | ||
|
|
3b8b315fea | ||
|
|
c65eefb954 | ||
|
|
997fd533ac | ||
|
|
bcfb5a8a70 | ||
|
|
049e9977f4 | ||
|
|
0334fc4cdf | ||
|
|
0c2334cefb | ||
|
|
dd7f1c1ea0 | ||
|
|
4bb242a4cc | ||
|
|
b577067379 | ||
|
|
bd4d4856ea | ||
|
|
c3a12ba5b7 | ||
|
|
478bf13a4a | ||
|
|
d8849f48da | ||
|
|
c466c553dc | ||
|
|
48afa6b433 | ||
|
|
e44b2895c9 | ||
|
|
85e5fc4018 | ||
|
|
70ccec9fef | ||
|
|
f7193594b1 | ||
|
|
9c7319634a | ||
|
|
3becb208ec | ||
|
|
1b00f9afa2 | ||
|
|
b58d4aed2f | ||
|
|
5adc67edf2 | ||
|
|
0ff0de8159 | ||
|
|
49b49271f3 | ||
|
|
5c5a6bd181 | ||
|
|
6ab1777f7c | ||
|
|
103ddf5c2e | ||
|
|
f9c94e8464 | ||
|
|
cdb0009e7c | ||
|
|
5010224500 | ||
|
|
1ebdd7e5bb | ||
|
|
0e0513e640 | ||
|
|
683b95c205 | ||
|
|
f28b43cc06 | ||
|
|
777a8a73ac | ||
|
|
77fc06991b | ||
|
|
eeb50e837d | ||
|
|
1b210714fd | ||
|
|
806bc01c17 | ||
|
|
0169097671 | ||
|
|
90c73237eb | ||
|
|
2a9c9551b8 | ||
|
|
a39728dff5 | ||
|
|
7048f385ef | ||
|
|
cb9c5746b0 | ||
|
|
ed36015d1e | ||
|
|
6ce4a08c53 | ||
|
|
4c379c2d4d | ||
|
|
fee43c00ca | ||
|
|
ee3060158e | ||
|
|
4e615d7e39 | ||
|
|
d1fea581d7 | ||
|
|
26a68cd477 | ||
|
|
eccf2b32ce | ||
|
|
6ff0d0a876 | ||
|
|
0bb779b7b6 | ||
|
|
51ebf3fa67 | ||
|
|
8cc6fd95f7 | ||
|
|
c5b422921b | ||
|
|
7b571e4d86 | ||
|
|
c39b554165 | ||
|
|
489ca67203 | ||
|
|
0804ea1418 | ||
|
|
84dbca97d5 | ||
|
|
8c350db146 | ||
|
|
471dace359 | ||
|
|
a01e6e5b16 | ||
|
|
96d03a5f59 | ||
|
|
993d407a48 | ||
|
|
2c739fbf02 | ||
|
|
dcd54266c0 | ||
|
|
0bf8979a09 | ||
|
|
b6ac303c96 | ||
|
|
406a41b91f | ||
|
|
adfb0daf7d | ||
|
|
a6d554fbc2 | ||
|
|
c6199cc0be | ||
|
|
ed2a591317 | ||
|
|
f6d5305c22 | ||
|
|
a6230419d8 | ||
|
|
b6cd520b72 | ||
|
|
68bfe93cf2 | ||
|
|
e6849cd9c9 | ||
|
|
d59350174c | ||
|
|
5f18ccd2bd | ||
|
|
58d879aec5 | ||
|
|
c9d07ce7bf | ||
|
|
bb39b97d1e | ||
|
|
b91769d931 | ||
|
|
ee5668a5cb | ||
|
|
67a3c598b1 | ||
|
|
ceb8858dc9 | ||
|
|
ed5dd43f37 | ||
|
|
8224b733db | ||
|
|
c1782bf4c3 | ||
|
|
cff310ad59 | ||
|
|
e9c5ae1683 | ||
|
|
09ab518007 | ||
|
|
246c1123fe |
2
.gitignore
vendored
@@ -408,3 +408,5 @@ FodyWeavers.xsd
|
||||
/DigitalData.Core.ConsoleApp/DigitalData.Core.ConsoleApp.csproj
|
||||
/DigitalData.Core.ConsoleApp/Program.cs
|
||||
/DigitalData.Core.ConsoleApp/FooHttpOptions.cs
|
||||
/DigitalData.Core.Tests/obj/
|
||||
/DigitalData.Core.Terminal
|
||||
|
||||
|
Before Width: | Height: | Size: 1020 KiB |
@@ -1,5 +1,5 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace DigitalData.Core.API
|
||||
@@ -8,8 +8,8 @@ namespace DigitalData.Core.API
|
||||
[Route("api/[controller]")]
|
||||
public class BasicCRUDControllerBase<TCRUDService, TDto, TEntity, TId> : CRUDControllerBase<TCRUDService, TDto, TDto, TDto, TEntity, TId>
|
||||
where TCRUDService : ICRUDService<TDto, TDto, TDto, TEntity, TId>
|
||||
where TDto : class
|
||||
where TEntity : class
|
||||
where TDto : class, IUnique<TId>
|
||||
where TEntity : class, IUnique<TId>
|
||||
{
|
||||
public BasicCRUDControllerBase(ILogger logger, TCRUDService service) : base(logger, service)
|
||||
{
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -19,8 +20,8 @@ namespace DigitalData.Core.API
|
||||
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCreateDto : class
|
||||
where TReadDto : class
|
||||
where TUpdateDto : class
|
||||
where TEntity : class
|
||||
where TUpdateDto : class, IUnique<TId>
|
||||
where TEntity : class, IUnique<TId>
|
||||
{
|
||||
protected readonly ILogger _logger;
|
||||
protected readonly TCRUDService _service;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -20,8 +21,8 @@ namespace DigitalData.Core.API
|
||||
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCreateDto : class
|
||||
where TReadDto : class
|
||||
where TUpdateDto : class
|
||||
where TEntity : class
|
||||
where TUpdateDto : class, IUnique<TId>
|
||||
where TEntity : class, IUnique<TId>
|
||||
{
|
||||
protected readonly ILogger _logger;
|
||||
protected readonly TCRUDService _service;
|
||||
|
||||
@@ -1,23 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<IsPackable>true</IsPackable>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<OutputType>Library</OutputType>
|
||||
<Description>This package provides a comprehensive set of API controllers and related utilities for the DigitalData.Core library. It includes generic CRUD controllers, localization extensions, middleware for security policies, and application model conventions.</Description>
|
||||
<PackageId>DigitalData.Core.API</PackageId>
|
||||
<Version>1.0.2.1</Version>
|
||||
<Version>2.0.0.0</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.API</Product>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core api</PackageTags>
|
||||
<PackageIcon>Assets\icon.png</PackageIcon>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\nuget-package-icons\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -12,13 +12,13 @@ namespace DigitalData.Core.API
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ReadControllerBase<TBasicCRUDService, TReadDto, TEntity, TId> : ControllerBase
|
||||
where TBasicCRUDService : IBasicCRUDService<TReadDto, TEntity, TId>
|
||||
public class ReadControllerBase<TReadService, TReadDto, TEntity, TId> : ControllerBase
|
||||
where TReadService : IReadService<TReadDto, TEntity, TId>
|
||||
where TReadDto : class
|
||||
where TEntity : class
|
||||
{
|
||||
protected readonly ILogger _logger;
|
||||
protected readonly TBasicCRUDService _service;
|
||||
protected readonly TReadService _service;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDControllerBase class with specified logger and CRUD service.
|
||||
@@ -27,7 +27,7 @@ namespace DigitalData.Core.API
|
||||
/// <param name="service">The CRUD service handling business logic for the entity.</param>
|
||||
public ReadControllerBase(
|
||||
ILogger logger,
|
||||
TBasicCRUDService service)
|
||||
TReadService service)
|
||||
{
|
||||
_logger = logger;
|
||||
_service = service;
|
||||
|
||||
@@ -13,13 +13,13 @@ namespace DigitalData.Core.API
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class ReadControllerBaseWithErrorHandling<TBasicCRUDService, TReadDto, TEntity, TId> : ControllerBase
|
||||
where TBasicCRUDService : IBasicCRUDService<TReadDto, TEntity, TId>
|
||||
public class ReadControllerBaseWithErrorHandling<TReadService, TReadDto, TEntity, TId> : ControllerBase
|
||||
where TReadService : IReadService<TReadDto, TEntity, TId>
|
||||
where TReadDto : class
|
||||
where TEntity : class
|
||||
{
|
||||
protected readonly ILogger _logger;
|
||||
protected readonly TBasicCRUDService _service;
|
||||
protected readonly TReadService _service;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDControllerBase class with specified logger and CRUD service.
|
||||
@@ -28,7 +28,7 @@ namespace DigitalData.Core.API
|
||||
/// <param name="service">The CRUD service handling business logic for the entity.</param>
|
||||
public ReadControllerBaseWithErrorHandling(
|
||||
ILogger logger,
|
||||
TBasicCRUDService service)
|
||||
TReadService service)
|
||||
{
|
||||
_logger = logger;
|
||||
_service = service;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace DigitalData.Core.Abstractions.Application
|
||||
/// allowing for a more concise and maintainable codebase when implementing services for such entities.
|
||||
/// </remarks>
|
||||
public interface IBasicCRUDService<TDto, TEntity, TId> : ICRUDService<TDto, TDto, TDto, TEntity, TId>
|
||||
where TDto : class where TEntity : class
|
||||
where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,18 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.Core.DTO;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Application
|
||||
{
|
||||
public interface ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCreateDto : class where TReadDto : class where TUpdateDto : class where TEntity : class
|
||||
public interface ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
|
||||
where TCreateDto : class where TReadDto : class where TUpdateDto : IUnique<TId> where TEntity : class, IUnique<TId>
|
||||
{
|
||||
/// <summary>
|
||||
/// Asynchronously creates a new entity based on the provided <paramref name="createDto"/> and returns the identifier of the created entity wrapped in a <see cref="DataResult{TId}"/>.
|
||||
/// The <see cref="DataResult{TId}"/> contains the identifier of the newly created entity on success or an error message on failure.
|
||||
/// </summary>
|
||||
/// <param name="createDto">The data transfer object containing the information for the new entity.</param>
|
||||
/// <returns>A task representing the asynchronous operation, with a <see cref="DataResult{TId}"/> containing the identifier of the created entity or an error message.</returns>
|
||||
Task<DataResult<TId>> CreateAsync(TCreateDto createDto);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an entity by its identifier and returns its readDTO representation wrapped in an IServiceResult,
|
||||
/// including the readDTO on success or null and an error message on failure.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to retrieve.</param>
|
||||
/// <returns>An DataResult containing the readDTO representing the found entity or null, with an appropriate message.</returns>
|
||||
Task<DataResult<TReadDto>> ReadByIdAsync(TId id);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all entities and returns their readDTO representations wrapped in an IServiceResult,
|
||||
/// including a collection of readDTOs on success or an error message on failure.
|
||||
/// </summary>
|
||||
/// <returns>An DataResult containing a collection of readDTOs representing all entities or an error message.</returns>
|
||||
Task<DataResult<IEnumerable<TReadDto>>> ReadAllAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Updates an existing entity based on the provided updateDTO and returns the result wrapped in an IServiceMessage,
|
||||
@@ -30,31 +21,5 @@ namespace DigitalData.Core.Abstractions.Application
|
||||
/// <param name="updateDto">The updateDTO with updated values for the entity.</param>
|
||||
/// <returns>An Result indicating the outcome of the update operation, with an appropriate message.</returns>
|
||||
Task<Result> UpdateAsync(TUpdateDto updateDto);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an entity by its identifier and returns the result wrapped in an IServiceMessage,
|
||||
/// indicating the success or failure of the operation, including the error messages on failure.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to delete.</param>
|
||||
/// <returns>An Result indicating the outcome of the delete operation, with an appropriate message.</returns>
|
||||
Task<Result> DeleteAsyncById(TId id);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously checks if an entity with the specified identifier exists within the data store.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to check.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns>
|
||||
Task<bool> HasEntity(TId id);
|
||||
|
||||
/// <summary>
|
||||
/// Handles exceptions that occur within service actions. This method should log the exception
|
||||
/// and return an String that contains information about the error, which can then be sent to the client.
|
||||
/// The implementation should determine the appropriate level of detail to include in the error message
|
||||
/// based on security and usability considerations.
|
||||
/// </summary>
|
||||
/// <param name="ex">The exception that occurred during the controller action.</param>
|
||||
/// <returns>An string instance representing the outcome of the error handling process.
|
||||
/// This includes a flag indicating the operation was unsuccessful and any relevant error messages.</returns>
|
||||
string HandleException(Exception ex);
|
||||
}
|
||||
}
|
||||
38
DigitalData.Core.Abstractions/Application/IReadService.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using DigitalData.Core.DTO;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Application
|
||||
{
|
||||
public interface IReadService<TReadDto, TEntity, TId>
|
||||
where TReadDto : class where TEntity : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves an entity by its identifier and returns its readDTO representation wrapped in an IServiceResult,
|
||||
/// including the readDTO on success or null and an error message on failure.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to retrieve.</param>
|
||||
/// <returns>An DataResult containing the readDTO representing the found entity or null, with an appropriate message.</returns>
|
||||
Task<DataResult<TReadDto>> ReadByIdAsync(TId id);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all entities and returns their readDTO representations wrapped in an IServiceResult,
|
||||
/// including a collection of readDTOs on success or an error message on failure.
|
||||
/// </summary>
|
||||
/// <returns>An DataResult containing a collection of readDTOs representing all entities or an error message.</returns>
|
||||
Task<DataResult<IEnumerable<TReadDto>>> ReadAllAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an entity by its identifier and returns the result wrapped in an IServiceMessage,
|
||||
/// indicating the success or failure of the operation, including the error messages on failure.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to delete.</param>
|
||||
/// <returns>An Result indicating the outcome of the delete operation, with an appropriate message.</returns>
|
||||
Task<Result> DeleteAsyncById(TId id);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously checks if an entity with the specified identifier exists within the data store.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to check.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns>
|
||||
Task<bool> HasEntity(TId id);
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1020 KiB |
@@ -4,15 +4,17 @@ namespace DigitalData.Core.Abstractions.Client
|
||||
{
|
||||
public interface IBaseHttpClientService
|
||||
{
|
||||
public string Uri { get; init; }
|
||||
|
||||
public CookieCollection GetCookies(string route = "");
|
||||
CookieCollection GetCookies(string path = "");
|
||||
|
||||
Task<HttpResponseMessage> FetchAsync(
|
||||
string route = "",
|
||||
string? scheme = null,
|
||||
int? port = null,
|
||||
string path = "",
|
||||
IEnumerable<KeyValuePair<string, object?>>? queryParams = null,
|
||||
HttpMethod? method = null,
|
||||
HttpContent? body = null,
|
||||
Dictionary<string, string>? form = null,
|
||||
IEnumerable<KeyValuePair<string, object>>? form = null,
|
||||
IEnumerable<KeyValuePair<string, object>>? headers = null,
|
||||
bool sendWithCookie = true,
|
||||
bool saveCookie = true
|
||||
);
|
||||
|
||||
13
DigitalData.Core.Abstractions/Client/IHttpClientOptions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace DigitalData.Core.Abstractions.Client
|
||||
{
|
||||
public interface IHttpClientOptions
|
||||
{
|
||||
string Uri { get; init; }
|
||||
|
||||
string? Path { get; init; }
|
||||
|
||||
Dictionary<string, object>? Headers { get; init; }
|
||||
|
||||
Dictionary<string, object?>? QueryParams { get; init; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace DigitalData.Core.Abstractions.Client
|
||||
{
|
||||
public interface IHttpClientService<TClientOptions> : IBaseHttpClientService
|
||||
public interface IHttpClientService<TClientOptions> : IBaseHttpClientService where TClientOptions : IHttpClientOptions
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<!-- NuGet Package Metadata -->
|
||||
@@ -16,11 +16,19 @@
|
||||
<PackageProjectUrl></PackageProjectUrl>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackAsTool>False</PackAsTool>
|
||||
<NeutralLanguage>aa-DJ</NeutralLanguage>
|
||||
<PackageIcon>Assets\icon.png</PackageIcon>
|
||||
<Version>1.0.1.1</Version>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<Version>2.2.1</Version>
|
||||
<AssemblyVersion>2.2.1</AssemblyVersion>
|
||||
<FileVersion>2.2.1</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\nuget-package-icons\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />
|
||||
@@ -33,12 +41,4 @@
|
||||
<ProjectReference Include="..\DigitalData.Core.DTO\DigitalData.Core.DTO.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\icon.png">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
7
DigitalData.Core.Abstractions/IUnique.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace DigitalData.Core.Abstractions
|
||||
{
|
||||
public interface IUnique<T>
|
||||
{
|
||||
public T Id { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity this repository works with.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
public interface ICRUDRepository<TEntity, TId> where TEntity : class
|
||||
public interface ICRUDRepository<TEntity, TId> where TEntity : class, IUnique<TId>
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds a new entity to the repository.
|
||||
@@ -40,5 +40,23 @@
|
||||
/// <param name="entity">The entity to delete.</param>
|
||||
/// <returns>If entity is deleted, return true othwerwise return false.</returns>
|
||||
Task<bool> DeleteAsync(TEntity entity);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously counts all entities in the repository.
|
||||
/// </summary>
|
||||
/// <returns>The total number of entities in the repository.</returns>
|
||||
Task<int> CountAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously counts the number of entities in the repository that match a specific identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entities to count.</param>
|
||||
/// <returns>The number of entities with the specified identifier.</returns>
|
||||
/// <remarks>
|
||||
/// This method provides a count of entities in the database that match the given identifier.
|
||||
/// If there are multiple entities with the same identifier, they will all be counted.
|
||||
/// The default implementation assumes that the identifier is unique for each entity.
|
||||
/// </remarks>
|
||||
Task<int> CountAsync(TId id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public static class CryptographerExtensions
|
||||
{
|
||||
public static IEnumerable<TRSACryptographer> GetByIssuer<TRSACryptographer>(this IEnumerable<TRSACryptographer> cryptographers, string issuer) where TRSACryptographer: IRSACryptographer
|
||||
=> cryptographers.Where(c => c.Issuer == issuer);
|
||||
|
||||
public static IEnumerable<TRSACryptographer> GetByAudience<TRSACryptographer>(this IEnumerable<TRSACryptographer> cryptographers, string audience) where TRSACryptographer : IRSACryptographer
|
||||
=> cryptographers.Where(c => c.Audience == audience);
|
||||
|
||||
public static TRSACryptographer Get<TRSACryptographer>(this IEnumerable<TRSACryptographer> cryptographers, string issuer, string audience) where TRSACryptographer : IRSACryptographer
|
||||
=> cryptographers.Where(c => c.Issuer == issuer && c.Audience == audience).SingleOrDefault()
|
||||
?? throw new InvalidOperationException($"No {typeof(TRSACryptographer).GetType().Name.TrimStart('I')} found with Issuer: {issuer} and Audience: {audience}.");
|
||||
|
||||
public static bool TryGet<TRSACryptographer>(this IEnumerable<TRSACryptographer> cryptographers, string issuer, string audience, out TRSACryptographer? cryptographer) where TRSACryptographer : IRSACryptographer
|
||||
{
|
||||
cryptographer = cryptographers.SingleOrDefault(c => c.Issuer == issuer && c.Audience == audience);
|
||||
return cryptographer is not null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IAsymCryptService<TParams> : IRSAFactory<TParams>
|
||||
{
|
||||
public IEnumerable<IRSADecryptor> Decryptors { get; }
|
||||
|
||||
public IEnumerable<IRSAEncryptor> Encryptors { get; }
|
||||
}
|
||||
}
|
||||
21
DigitalData.Core.Abstractions/Security/IRSACryptographer.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IRSACryptographer
|
||||
{
|
||||
public string Pem { get; init; }
|
||||
|
||||
public RSAEncryptionPadding Padding { get; init; }
|
||||
|
||||
public string? Directory { get; set; }
|
||||
|
||||
public string? FileName { get; set; }
|
||||
|
||||
public string Issuer { get; init; }
|
||||
|
||||
public string Audience { get; init; }
|
||||
|
||||
public void Init();
|
||||
}
|
||||
}
|
||||
13
DigitalData.Core.Abstractions/Security/IRSADecryptor.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IRSADecryptor : IRSACryptographer
|
||||
{
|
||||
public bool Encrypt { get; init; }
|
||||
|
||||
IRSAEncryptor Encryptor { get; }
|
||||
|
||||
byte[] Decrypt(byte[] data);
|
||||
|
||||
string Decrypt(string data);
|
||||
}
|
||||
}
|
||||
11
DigitalData.Core.Abstractions/Security/IRSAEncryptor.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IRSAEncryptor : IRSACryptographer
|
||||
{
|
||||
public byte[] Encrypt(byte[] data);
|
||||
|
||||
public string Encrypt(string data);
|
||||
|
||||
public bool Verify(string data, string signature) => Encrypt(data) == signature;
|
||||
}
|
||||
}
|
||||
16
DigitalData.Core.Abstractions/Security/IRSAFactory.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IRSAFactory<TParams>
|
||||
{
|
||||
string CreateRSAPrivateKeyPem(int? keySizeInBits = null);
|
||||
|
||||
string CreateEncryptedPrivateKeyPem(
|
||||
int? keySizeInBits = null,
|
||||
string? password = null,
|
||||
PbeEncryptionAlgorithm? pbeEncryptionAlgorithm = null,
|
||||
HashAlgorithmName? hashAlgorithmName = null,
|
||||
int? iterationCount = null);
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1020 KiB |
@@ -1,4 +1,5 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
|
||||
@@ -19,7 +20,7 @@ namespace DigitalData.Core.Application
|
||||
/// </remarks>
|
||||
public class BasicCRUDService<TCRUDRepository, TDto, TEntity, TId> :
|
||||
CRUDService<TCRUDRepository, TDto, TDto, TDto, TEntity, TId>, IBasicCRUDService<TDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class where TEntity : class
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the BasicCRUDService with the specified repository, translation service, and AutoMapper configuration.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using AutoMapper;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.Core.Abstractions;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
@@ -15,25 +15,17 @@ namespace DigitalData.Core.Application
|
||||
/// <typeparam name="TUpdateDto">The DTO type for update operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : class where TEntity : class
|
||||
public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ReadService<TCRUDRepository, TReadDto, TEntity, TId>, ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : IUnique<TId> where TEntity : class, IUnique<TId>
|
||||
{
|
||||
protected readonly TCRUDRepository _repository;
|
||||
protected readonly IMapper _mapper;
|
||||
protected readonly PropertyInfo? _keyPropertyInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDService class with the specified repository, translation service, and mapper.
|
||||
/// </summary>
|
||||
/// <param name="repository">The CRUD repository for accessing the database.</param>
|
||||
/// <param name="mapper">The AutoMapper instance for mapping between DTOs and entity objects.</param>
|
||||
public CRUDService(TCRUDRepository repository, IMapper mapper)
|
||||
public CRUDService(TCRUDRepository repository, IMapper mapper) : base(repository: repository, mapper: mapper)
|
||||
{
|
||||
_repository = repository;
|
||||
_mapper = mapper;
|
||||
|
||||
_keyPropertyInfo = typeof(TEntity).GetProperties()
|
||||
.FirstOrDefault(prop => Attribute.IsDefined(prop, typeof(KeyAttribute)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -43,33 +35,9 @@ namespace DigitalData.Core.Application
|
||||
/// <returns>A service result indicating success or failure, including the entity DTO.</returns>
|
||||
public virtual async Task<DataResult<TId>> CreateAsync(TCreateDto createDto)
|
||||
{
|
||||
var entity = _mapper.MapOrThrow<TEntity>(createDto);
|
||||
var entity = _mapper.Map<TEntity>(createDto);
|
||||
var createdEntity = await _repository.CreateAsync(entity);
|
||||
return createdEntity is null ? Result.Fail<TId>() : Result.Success(KeyValueOf(createdEntity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously reads an entity by its identifier and maps it to a read DTO.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to read.</param>
|
||||
/// <returns>A service result indicating success or failure, including the read DTO if successful.</returns>
|
||||
public virtual async Task<DataResult<TReadDto>> ReadByIdAsync(TId id)
|
||||
{
|
||||
var entity = await _repository.ReadByIdAsync(id);
|
||||
return entity is null
|
||||
? Result.Fail<TReadDto>()
|
||||
: Result.Success(_mapper.MapOrThrow<TReadDto>(entity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously reads all entities and maps them to read DTOs.
|
||||
/// </summary>
|
||||
/// <returns>A service result including a collection of read DTOs.</returns>
|
||||
public virtual async Task<DataResult<IEnumerable<TReadDto>>> ReadAllAsync()
|
||||
{
|
||||
var entities = await _repository.ReadAllAsync();
|
||||
var readDto = _mapper.MapOrThrow<IEnumerable<TReadDto>>(entities);
|
||||
return Result.Success(readDto);
|
||||
return createdEntity is null ? Result.Fail<TId>() : Result.Success(createdEntity.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -79,64 +47,16 @@ namespace DigitalData.Core.Application
|
||||
/// <returns>A service message indicating success or failure.</returns>
|
||||
public virtual async Task<Result> UpdateAsync(TUpdateDto updateDto)
|
||||
{
|
||||
var entity = _mapper.MapOrThrow<TEntity>(updateDto);
|
||||
bool isUpdated = await _repository.UpdateAsync(entity);
|
||||
return isUpdated ? Result.Success() : Result.Fail();
|
||||
}
|
||||
var currentEntitiy = await _repository.ReadByIdAsync(updateDto.Id);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deletes an entity by its identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to delete.</param>
|
||||
/// <returns>A service message indicating success or failure.</returns>
|
||||
public virtual async Task<Result> DeleteAsyncById(TId id)
|
||||
{
|
||||
TEntity? entity = await _repository.ReadByIdAsync(id);
|
||||
if (currentEntitiy is null)
|
||||
return Result.Fail().Notice(LogLevel.Warning, Flag.NotFound, $"{updateDto.Id} is not found in update process of {GetType()} entity.");
|
||||
|
||||
var entity = _mapper.Map(updateDto, currentEntitiy);
|
||||
|
||||
if (entity is null)
|
||||
return Result.Fail();
|
||||
|
||||
bool isDeleted = await _repository.DeleteAsync(entity);
|
||||
return isDeleted ? Result.Success() : Result.Fail();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously checks if an entity with the specified identifier exists.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to check.</param>
|
||||
/// <returns>A Task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns>
|
||||
public virtual async Task<bool> HasEntity(TId id)
|
||||
{
|
||||
var entity = await _repository.ReadByIdAsync(id);
|
||||
return entity is not null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the ID value of an entity based on the defined [Key] attribute.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity from which to extract the ID.</param>
|
||||
/// <returns>The ID of the entity.</returns>
|
||||
protected virtual TId KeyValueOf(TEntity entity)
|
||||
{
|
||||
if (_keyPropertyInfo is null)
|
||||
throw new InvalidOperationException($"No property with [Key] attribute found on {typeof(TEntity).Name} entity.");
|
||||
|
||||
object idObj = _keyPropertyInfo?.GetValue(entity) ?? throw new InvalidOperationException($"The ID property of {typeof(TEntity).Name} entity cannot be null.");
|
||||
|
||||
if (idObj is TId id)
|
||||
return id;
|
||||
else
|
||||
throw new InvalidCastException($"The ID of {typeof(TEntity).Name} entity must be type of {typeof(TId).Name}, but it is type of {idObj.GetType().Name}.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles exceptions that occur during CRUD operations, providing a structured string.
|
||||
/// </summary>
|
||||
/// <param name="ex">The exception that was caught during CRUD operations.</param>
|
||||
/// <returns>A <see cref="IServiceMessage"/> containing information about the failure, including a user-friendly error message and additional error details.</returns>
|
||||
public virtual string HandleException(Exception ex)
|
||||
{
|
||||
return $"An unexpected error occurred on the server side. Please inform the IT support team.\n{ex.GetType().Name}\n{ex.Message}";
|
||||
return await _repository.UpdateAsync(entity)
|
||||
? Result.Success()
|
||||
: Result.Fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
@@ -23,7 +24,7 @@ namespace DigitalData.Core.Application
|
||||
/// <param name="configureService">An optional action to configure additional services for the CRUD service.</param>
|
||||
/// <returns>The original <see cref="IServiceCollection"/> instance, allowing further configuration.</returns>
|
||||
public static IServiceCollection AddCleanBasicCRUDService<TCRUDRepository, TDto, TEntity, TId, TProfile>(this IServiceCollection services, Action<IServiceCollection>? configureService = null)
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class where TEntity : class where TProfile : Profile
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId> where TProfile : Profile
|
||||
{
|
||||
services.AddScoped<IBasicCRUDService<TDto, TEntity, TId>, BasicCRUDService<TCRUDRepository, TDto, TEntity, TId>>();
|
||||
configureService?.Invoke(services);
|
||||
@@ -47,7 +48,7 @@ namespace DigitalData.Core.Application
|
||||
/// <param name="configureService">An optional action to configure additional services for the CRUD service.</param>
|
||||
/// <returns>The original <see cref="IServiceCollection"/> instance, allowing further configuration.</returns>
|
||||
public static IServiceCollection AddCleanCRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId, TProfile>(this IServiceCollection services, Action<IServiceCollection>? configureService = null)
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : class where TEntity : class where TProfile : Profile
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : class, IUnique<TId> where TEntity : class, IUnique<TId> where TProfile : Profile
|
||||
{
|
||||
services.AddScoped<ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>, CRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>>();
|
||||
configureService?.Invoke(services);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
@@ -11,13 +11,14 @@
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.Application</Product>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core application clean architecture</PackageTags>
|
||||
<Version>2.0.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\DigitalData.Core.Abstractions\Assets\icon.png">
|
||||
<None Include="..\..\nuget-package-icons\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
@@ -38,11 +39,4 @@
|
||||
<ProjectReference Include="..\DigitalData.Core.Abstractions\DigitalData.Core.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\icon.png">
|
||||
<PackagePath>\</PackagePath>
|
||||
<Pack>True</Pack>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
79
DigitalData.Core.Application/ReadService.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
using DigitalData.Core.Abstractions.Application;
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.DTO;
|
||||
using DigitalData.Core.Abstractions;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides generic Read (Read and Delete) operations for a specified type of entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TReadDto">The DTO type for read operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
public class ReadService<TCRUDRepository, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TReadDto : class where TEntity : class, IUnique<TId>
|
||||
{
|
||||
protected readonly TCRUDRepository _repository;
|
||||
protected readonly IMapper _mapper;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the CRUDService class with the specified repository, translation service, and mapper.
|
||||
/// </summary>
|
||||
/// <param name="repository">The CRUD repository for accessing the database.</param>
|
||||
/// <param name="mapper">The AutoMapper instance for mapping between DTOs and entity objects.</param>
|
||||
public ReadService(TCRUDRepository repository, IMapper mapper)
|
||||
{
|
||||
_repository = repository;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously reads an entity by its identifier and maps it to a read DTO.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to read.</param>
|
||||
/// <returns>A service result indicating success or failure, including the read DTO if successful.</returns>
|
||||
public virtual async Task<DataResult<TReadDto>> ReadByIdAsync(TId id)
|
||||
{
|
||||
var entity = await _repository.ReadByIdAsync(id);
|
||||
return entity is null
|
||||
? Result.Fail<TReadDto>()
|
||||
: Result.Success(_mapper.Map<TReadDto>(entity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously reads all entities and maps them to read DTOs.
|
||||
/// </summary>
|
||||
/// <returns>A service result including a collection of read DTOs.</returns>
|
||||
public virtual async Task<DataResult<IEnumerable<TReadDto>>> ReadAllAsync()
|
||||
{
|
||||
var entities = await _repository.ReadAllAsync();
|
||||
var readDto = _mapper.Map<IEnumerable<TReadDto>>(entities);
|
||||
return Result.Success(readDto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously deletes an entity by its identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to delete.</param>
|
||||
/// <returns>A service message indicating success or failure.</returns>
|
||||
public virtual async Task<Result> DeleteAsyncById(TId id)
|
||||
{
|
||||
TEntity? entity = await _repository.ReadByIdAsync(id);
|
||||
|
||||
if (entity is null)
|
||||
return Result.Fail();
|
||||
|
||||
bool isDeleted = await _repository.DeleteAsync(entity);
|
||||
return isDeleted ? Result.Success() : Result.Fail();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously checks if an entity with the specified identifier exists.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entity to check.</param>
|
||||
/// <returns>A Task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns>
|
||||
public virtual async Task<bool> HasEntity(TId id) => await _repository.CountAsync(id) > 0;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<ImportGroup Condition=" '$(TargetFramework)' == 'net7.0' AND '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition=" '$(TargetFramework)' == 'net8.0' AND '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
Before Width: | Height: | Size: 1020 KiB |
@@ -1,44 +1,113 @@
|
||||
using DigitalData.Core.Abstractions.Client;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
using System.Web;
|
||||
|
||||
namespace DigitalData.Core.Client
|
||||
{
|
||||
public class BaseHttpClientService : IBaseHttpClientService
|
||||
{
|
||||
protected readonly HttpClient _client;
|
||||
protected readonly CookieContainer _cookies;
|
||||
protected readonly CookieContainer _cookies;
|
||||
|
||||
[StringSyntax("Uri")]
|
||||
public string Uri { get; init; }
|
||||
protected readonly string _uri;
|
||||
|
||||
public BaseHttpClientService(HttpClient client, CookieContainer cookieContainer, IOptions<HttpClientOptions> clientOptions)
|
||||
protected readonly string _path;
|
||||
|
||||
protected IEnumerable<KeyValuePair<string, object>>? _headers;
|
||||
|
||||
protected IEnumerable<KeyValuePair<string, object?>>? _queryParams;
|
||||
|
||||
internal BaseHttpClientService(HttpClient client, CookieContainer cookieContainer, IHttpClientOptions clientOptions)
|
||||
{
|
||||
_client = client;
|
||||
_cookies = cookieContainer;
|
||||
Uri = clientOptions.Value.Uri;
|
||||
_uri = clientOptions.Uri.Trim(URI_TRIM_CHARS);
|
||||
_path = clientOptions.Path?.Trim(URI_TRIM_CHARS) ?? string.Empty;
|
||||
_headers = clientOptions.Headers;
|
||||
_queryParams = clientOptions.QueryParams;
|
||||
}
|
||||
|
||||
public CookieCollection GetCookies(string route = "") => _cookies.GetCookies(uri: new Uri(Uri + route));
|
||||
public CookieCollection GetCookies(string path = "") => _cookies.GetCookies(uri: new Uri(UriCombine(_uri, path, path.Trim(URI_TRIM_CHARS))));
|
||||
|
||||
public async Task<HttpResponseMessage> FetchAsync(
|
||||
string route = "",
|
||||
string? scheme = null,
|
||||
int? port = null,
|
||||
string path = "",
|
||||
IEnumerable<KeyValuePair<string, object?>>? queryParams = null,
|
||||
HttpMethod? method = null,
|
||||
HttpContent? body = null,
|
||||
Dictionary<string, string>? form = null,
|
||||
IEnumerable<KeyValuePair<string, object>>? form = null,
|
||||
IEnumerable<KeyValuePair<string, object>>? headers = null,
|
||||
bool sendWithCookie = true,
|
||||
bool saveCookie = true
|
||||
)
|
||||
{
|
||||
// merge with default headers
|
||||
if(_headers is not null)
|
||||
{
|
||||
if (headers is null)
|
||||
headers = _headers;
|
||||
else
|
||||
{
|
||||
var mergedHeaders = headers.ToList();
|
||||
mergedHeaders.AddRange(_headers);
|
||||
headers = mergedHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
// Add default query parameters
|
||||
if(_queryParams is not null)
|
||||
{
|
||||
if (queryParams is null)
|
||||
queryParams = _queryParams;
|
||||
else
|
||||
{
|
||||
var mergedQueryParams = queryParams.ToList();
|
||||
mergedQueryParams.AddRange(_queryParams);
|
||||
queryParams = mergedQueryParams;
|
||||
}
|
||||
}
|
||||
|
||||
// set default HTTP method as GET
|
||||
method ??= HttpMethod.Get;
|
||||
|
||||
// create URL
|
||||
var requestUriStr = Uri + route;
|
||||
var requestUri = new Uri(requestUriStr);
|
||||
var uriBuilder = new UriBuilder(_uri);
|
||||
if (scheme is not null)
|
||||
uriBuilder.Scheme = scheme;
|
||||
if (port is int portInt)
|
||||
uriBuilder.Port = portInt;
|
||||
uriBuilder.Path = UriCombine(_path, path?.Trim(URI_TRIM_CHARS) ?? string.Empty);
|
||||
|
||||
var requestMessage = new HttpRequestMessage(method, requestUriStr);
|
||||
// Add query parameters if provided
|
||||
if (queryParams?.Any() ?? false)
|
||||
{
|
||||
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
|
||||
|
||||
var flagParams = queryParams.Where(param => param.Value is null).Select(param => param.Key);
|
||||
|
||||
var valueParams = queryParams.Where(param => param.Value is not null);
|
||||
|
||||
foreach (var param in valueParams)
|
||||
query[param.Key] = param.Value switch
|
||||
{
|
||||
bool b => b.ToString().ToLower(),
|
||||
_ => param.Value.ToString()
|
||||
};
|
||||
|
||||
if (flagParams.Any())
|
||||
uriBuilder.Query = string.Join(QUERY_SEPARATOR, query.ToString(), string.Join(QUERY_SEPARATOR, flagParams));
|
||||
else uriBuilder.Query = query.ToString();
|
||||
}
|
||||
|
||||
var requestUri = uriBuilder.Uri;
|
||||
|
||||
var requestMessage = new HttpRequestMessage(method, requestUri);
|
||||
|
||||
// Add headers if provided
|
||||
headers?.ForEach(header => requestMessage.Headers.Add(header.Key, header.Value.ToString()));
|
||||
|
||||
// Add cookie to request
|
||||
if (sendWithCookie)
|
||||
@@ -56,7 +125,7 @@ namespace DigitalData.Core.Client
|
||||
else if (body != null)
|
||||
requestMessage.Content = body;
|
||||
else if (form != null)
|
||||
requestMessage.Content = new FormUrlEncodedContent(form);
|
||||
requestMessage.Content = new FormUrlEncodedContent(form.Select(e => KeyValuePair.Create(e.Key, e.Value.ToString())));
|
||||
|
||||
var response = await _client.SendAsync(requestMessage);
|
||||
|
||||
@@ -68,5 +137,11 @@ namespace DigitalData.Core.Client
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
internal static readonly char[] URI_TRIM_CHARS = { '\\', '/', ' ' };
|
||||
|
||||
internal static string UriCombine(params string[] paths) => System.IO.Path.Combine(paths).Replace("\\", "/");
|
||||
|
||||
internal static readonly char QUERY_SEPARATOR = '&';
|
||||
}
|
||||
}
|
||||
@@ -1,33 +1,35 @@
|
||||
using DigitalData.Core.Abstractions.Client;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Net;
|
||||
|
||||
namespace DigitalData.Core.Client
|
||||
{
|
||||
public static class DIExtensions
|
||||
{
|
||||
public static IServiceCollection AddHttpClientService(this IServiceCollection services, string uri)
|
||||
internal static IServiceCollection AddHttpClientServiceDefaults(this IServiceCollection services)
|
||||
{
|
||||
services.TryAddSingleton<HttpClient>();
|
||||
services.TryAddSingleton<CookieContainer>();
|
||||
services.AddSingleton<IBaseHttpClientService, BaseHttpClientService>();
|
||||
services.Configure<HttpClientOptions>(opt => opt.Uri = uri);
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddHttpClientService<TClientOptions>(this IServiceCollection services, Action<TClientOptions>? clientOptions = null, bool setAsDefaultBase = false)
|
||||
where TClientOptions : HttpClientOptions
|
||||
public static IServiceCollection AddHttpClientService<THttpClientOptions>(this IServiceCollection services, IConfigurationSection section)
|
||||
where THttpClientOptions : class, IHttpClientOptions
|
||||
{
|
||||
services.TryAddSingleton<HttpClient>();
|
||||
services.TryAddSingleton<CookieContainer>();
|
||||
services.AddSingleton<IHttpClientService<TClientOptions>, HttpClientService<TClientOptions>>();
|
||||
services.Configure(clientOptions ?? (_ => { }));
|
||||
|
||||
if (setAsDefaultBase)
|
||||
services.AddSingleton<IBaseHttpClientService, HttpClientService<TClientOptions>>();
|
||||
services.AddHttpClientServiceDefaults();
|
||||
services.TryAddSingleton<IHttpClientService<THttpClientOptions>, HttpClientService<THttpClientOptions>>();
|
||||
return services.Configure<THttpClientOptions>(section);
|
||||
}
|
||||
|
||||
public static IServiceCollection AddHttpClientService<THttpClientOptions>(this IServiceCollection services, THttpClientOptions options)
|
||||
where THttpClientOptions : class, IHttpClientOptions
|
||||
{
|
||||
services.AddHttpClientServiceDefaults();
|
||||
services.TryAddSingleton<IHttpClientService<THttpClientOptions>, HttpClientService<THttpClientOptions>>();
|
||||
services.TryAddSingleton(Options.Create(options));
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,35 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Description>This package provides HTTP client extension methods for the DigitalData.Core library, offering simplified and asynchronous methods for fetching and handling HTTP responses. It includes utility methods for sending GET requests, reading response content as text or JSON, and deserializing JSON into dynamic or strongly-typed objects using Newtonsoft.Json. These extensions facilitate efficient and easy-to-read HTTP interactions in client applications.</Description>
|
||||
<PackageId>DigitalData.Core.Client</PackageId>
|
||||
<Version>1.0.1.1</Version>
|
||||
<Version>2.0.3</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>Digital Data GmbH</Product>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<PackageProjectUrl></PackageProjectUrl>
|
||||
<PackageIcon>Assets\icon.png</PackageIcon>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core http client json serilization</PackageTags>
|
||||
<AssemblyVersion>2.0.3</AssemblyVersion>
|
||||
<FileVersion>2.0.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\..\nuget-package-icons\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace DigitalData.Core.Client
|
||||
{
|
||||
public class HttpClientOptions
|
||||
{
|
||||
public string Uri { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,9 @@ using System.Net;
|
||||
namespace DigitalData.Core.Client
|
||||
{
|
||||
public class HttpClientService<TClientOptions> : BaseHttpClientService, IHttpClientService<TClientOptions>, IBaseHttpClientService
|
||||
where TClientOptions : HttpClientOptions
|
||||
where TClientOptions : class, IHttpClientOptions
|
||||
{
|
||||
public HttpClientService(HttpClient client, CookieContainer cookieContainer, IOptions<TClientOptions> clientOptions) : base(client, cookieContainer, clientOptions)
|
||||
public HttpClientService(HttpClient client, CookieContainer cookieContainer, IOptions<TClientOptions> clientOptions) : base(client, cookieContainer, clientOptions.Value)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace DigitalData.Core.Client
|
||||
|
||||
public static T Provide<T>() where T : notnull => _lazyProvider.Value.GetRequiredService<T>();
|
||||
|
||||
public static IHttpClientService<TOptions> ProvideHttpClientService<TOptions>() where TOptions : notnull
|
||||
public static IHttpClientService<TOptions> ProvideHttpClientService<TOptions>() where TOptions : IHttpClientOptions
|
||||
=> _lazyProvider.Value.GetRequiredService<IHttpClientService<TOptions>>();
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\tekh\.nuget\packages\;D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.9.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\tekh\.nuget\packages\" />
|
||||
<SourceRoot Include="D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,20 +0,0 @@
|
||||
using DigitalData.Common.CultureServices;
|
||||
using DigitalData.Core.Contracts.CultureServices;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace DigitalData.Core.CultureServices
|
||||
{
|
||||
public static class DIExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers the KeyTranslationService and its dependencies in the dependency injection container.
|
||||
/// </summary>
|
||||
/// <param name="services">The IServiceCollection instance to register the services with.</param>
|
||||
public static IServiceCollection AddKeyTranslationService(this IServiceCollection services)
|
||||
{
|
||||
services.AddTransient<IKeyTranslationService, KeyTranslationService>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.16" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.Contracts\DigitalData.Core.Contracts.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,20 +0,0 @@
|
||||
using DigitalData.Core.Contracts.CultureServices;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace DigitalData.Common.CultureServices
|
||||
{
|
||||
public class KeyTranslationService<TResouce> : IKeyTranslationService
|
||||
{
|
||||
private readonly IStringLocalizer<TResouce> _localizer;
|
||||
|
||||
public KeyTranslationService(IStringLocalizer<TResouce> localizer)
|
||||
{
|
||||
_localizer = localizer;
|
||||
}
|
||||
|
||||
public string Translate(string key, params object[] arguments) => _localizer[key, arguments];
|
||||
|
||||
|
||||
public string Translate(Enum key, params object[] arguments) => Translate(key.ToString(), arguments);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"profiles": {
|
||||
"DigitalData.Core.CultureServices": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:61600;http://localhost:61602"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
using DigitalData.Core.Contracts.CultureServices;
|
||||
|
||||
namespace DigitalData.Core.CultureServices
|
||||
{
|
||||
public static class TranslationExtensions
|
||||
{
|
||||
public static string TranslateWith(this string key, IKeyTranslationService keyTranslationService) => keyTranslationService.Translate(key: key);
|
||||
|
||||
public static string TranslateWith(this Enum key, IKeyTranslationService keyTranslationService) => keyTranslationService.Translate(key: key);
|
||||
}
|
||||
}
|
||||
@@ -1,576 +0,0 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v7.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v7.0": {
|
||||
"DigitalData.Core.CultureServices/1.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Localization": "7.0.16",
|
||||
"WebCore.Contracts": "1.0.1",
|
||||
"DigitalData.Core.Contracts": "1.0.1.0"
|
||||
},
|
||||
"runtime": {
|
||||
"DigitalData.Core.CultureServices.dll": {}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Caching.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Memory/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Caching.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "7.0.1",
|
||||
"Microsoft.Extensions.Options": "7.0.1",
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Caching.Memory.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Configuration.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder/7.0.4": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Configuration.Binder.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.423.11508"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Localization/7.0.16": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Localization.Abstractions": "7.0.16",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "7.0.1",
|
||||
"Microsoft.Extensions.Options": "7.0.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Localization.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.1624.6815"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Localization.Abstractions/7.0.16": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Localization.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.1624.6815"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions/7.0.1": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Logging.Abstractions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Options/7.0.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0",
|
||||
"Microsoft.Extensions.Primitives": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Options.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.323.6910"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Primitives/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Extensions.Primitives.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Abstractions/7.5.1": {
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Abstractions.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.JsonWebTokens/7.5.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Tokens": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.JsonWebTokens.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Logging/7.5.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Abstractions": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Logging.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IdentityModel.Tokens/7.5.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.Logging": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/Microsoft.IdentityModel.Tokens.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/Microsoft.Win32.SystemEvents.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/Microsoft.Win32.SystemEvents.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/7.0.0": {
|
||||
"dependencies": {
|
||||
"System.Diagnostics.EventLog": "7.0.0",
|
||||
"System.Security.Cryptography.ProtectedData": "7.0.0",
|
||||
"System.Security.Permissions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Configuration.ConfigurationManager.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Diagnostics.EventLog/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Diagnostics.EventLog.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.Diagnostics.EventLog.Messages.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "0.0.0.0"
|
||||
},
|
||||
"runtimes/win/lib/net7.0/System.Diagnostics.EventLog.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.DirectoryServices/7.0.1": {
|
||||
"dependencies": {
|
||||
"System.Security.Permissions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.DirectoryServices.dll": {
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "7.0.323.6910"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.DirectoryServices.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "7.0.323.6910"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.DirectoryServices.AccountManagement/7.0.1": {
|
||||
"dependencies": {
|
||||
"System.Configuration.ConfigurationManager": "7.0.0",
|
||||
"System.DirectoryServices": "7.0.1",
|
||||
"System.DirectoryServices.Protocols": "7.0.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.DirectoryServices.AccountManagement.dll": {
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "7.0.1123.42427"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.DirectoryServices.AccountManagement.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "7.0.1123.42427"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.DirectoryServices.Protocols/7.0.1": {
|
||||
"runtime": {
|
||||
"lib/net7.0/System.DirectoryServices.Protocols.dll": {
|
||||
"assemblyVersion": "7.0.0.1",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/linux/lib/net7.0/System.DirectoryServices.Protocols.dll": {
|
||||
"rid": "linux",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.1",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
},
|
||||
"runtimes/osx/lib/net7.0/System.DirectoryServices.Protocols.dll": {
|
||||
"rid": "osx",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.1",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
},
|
||||
"runtimes/win/lib/net7.0/System.DirectoryServices.Protocols.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.1",
|
||||
"fileVersion": "7.0.723.27404"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Drawing.Common/7.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.SystemEvents": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Drawing.Common.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.Drawing.Common.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt/7.5.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.IdentityModel.JsonWebTokens": "7.5.1",
|
||||
"Microsoft.IdentityModel.Tokens": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/System.IdentityModel.Tokens.Jwt.dll": {
|
||||
"assemblyVersion": "7.5.1.0",
|
||||
"fileVersion": "7.5.1.50405"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/7.0.0": {
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Security.Permissions/7.0.0": {
|
||||
"dependencies": {
|
||||
"System.Windows.Extensions": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Security.Permissions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Windows.Extensions/7.0.0": {
|
||||
"dependencies": {
|
||||
"System.Drawing.Common": "7.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net7.0/System.Windows.Extensions.dll": {
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
},
|
||||
"runtimeTargets": {
|
||||
"runtimes/win/lib/net7.0/System.Windows.Extensions.dll": {
|
||||
"rid": "win",
|
||||
"assetType": "runtime",
|
||||
"assemblyVersion": "7.0.0.0",
|
||||
"fileVersion": "7.0.22.51805"
|
||||
}
|
||||
}
|
||||
},
|
||||
"WebCore.Contracts/1.0.1": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Caching.Memory": "7.0.0",
|
||||
"Microsoft.Extensions.Configuration.Binder": "7.0.4",
|
||||
"System.DirectoryServices": "7.0.1",
|
||||
"System.DirectoryServices.AccountManagement": "7.0.1",
|
||||
"System.IdentityModel.Tokens.Jwt": "7.5.1"
|
||||
},
|
||||
"runtime": {
|
||||
"DigitalData.Core.Contracts.dll": {}
|
||||
}
|
||||
},
|
||||
"DigitalData.Core.Contracts/1.0.1.0": {
|
||||
"runtime": {
|
||||
"DigitalData.Core.Contracts.dll": {
|
||||
"assemblyVersion": "1.0.1.0",
|
||||
"fileVersion": "1.0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"DigitalData.Core.CultureServices/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Abstractions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-IeimUd0TNbhB4ded3AbgBLQv2SnsiVugDyGV1MvspQFVlA07nDC7Zul7kcwH5jWN3JiTcp/ySE83AIJo8yfKjg==",
|
||||
"path": "microsoft.extensions.caching.abstractions/7.0.0",
|
||||
"hashPath": "microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Caching.Memory/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-xpidBs2KCE2gw1JrD0quHE72kvCaI3xFql5/Peb2GRtUuZX+dYPoK/NTdVMiM67Svym0M0Df9A3xyU0FbMQhHw==",
|
||||
"path": "microsoft.extensions.caching.memory/7.0.0",
|
||||
"hashPath": "microsoft.extensions.caching.memory.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Abstractions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-f34u2eaqIjNO9YLHBz8rozVZ+TcFiFs0F3r7nUJd7FRkVSxk8u4OpoK226mi49MwexHOR2ibP9MFvRUaLilcQQ==",
|
||||
"path": "microsoft.extensions.configuration.abstractions/7.0.0",
|
||||
"hashPath": "microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder/7.0.4": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-8+XPvJnHZsYgHOQlcMuQe7QNF5KdVKHH1F/wW3nd8/u81Gk/XFAYMDP0Lpz18h7/AM95M662vvqMorcYxCBB4w==",
|
||||
"path": "microsoft.extensions.configuration.binder/7.0.4",
|
||||
"hashPath": "microsoft.extensions.configuration.binder.7.0.4.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-h3j/QfmFN4S0w4C2A6X7arXij/M/OVw3uQHSOFxnND4DyAzO1F9eMX7Eti7lU/OkSthEE0WzRsfT/Dmx86jzCw==",
|
||||
"path": "microsoft.extensions.dependencyinjection.abstractions/7.0.0",
|
||||
"hashPath": "microsoft.extensions.dependencyinjection.abstractions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Localization/7.0.16": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-JpTQ/El4m/Yfup+sgwvp8qtYAoxEYe9wXy63gw/KXep8bzUdA1wfReed0rL2UqR9Uk7hDnjfYFCz190B2fBYdA==",
|
||||
"path": "microsoft.extensions.localization/7.0.16",
|
||||
"hashPath": "microsoft.extensions.localization.7.0.16.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Localization.Abstractions/7.0.16": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-wUwfDVcOMRUZv+zX45Vyh/MkXpdOy7nIvRRf3n2iiYoh76M0Dr/wx8Ppxk3v9H556z2e0QwLVQqqkd+oj+CGRQ==",
|
||||
"path": "microsoft.extensions.localization.abstractions/7.0.16",
|
||||
"hashPath": "microsoft.extensions.localization.abstractions.7.0.16.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Logging.Abstractions/7.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-pkeBFx0vqMW/A3aUVHh7MPu3WkBhaVlezhSZeb1c9XD0vUReYH1TLFSy5MxJgZfmz5LZzYoErMorlYZiwpOoNA==",
|
||||
"path": "microsoft.extensions.logging.abstractions/7.0.1",
|
||||
"hashPath": "microsoft.extensions.logging.abstractions.7.0.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Options/7.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-pZRDYdN1FpepOIfHU62QoBQ6zdAoTvnjxFfqAzEd9Jhb2dfhA5i6jeTdgGgcgTWFRC7oT0+3XrbQu4LjvgX1Nw==",
|
||||
"path": "microsoft.extensions.options/7.0.1",
|
||||
"hashPath": "microsoft.extensions.options.7.0.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Extensions.Primitives/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-um1KU5kxcRp3CNuI8o/GrZtD4AIOXDk+RLsytjZ9QPok3ttLUelLKpilVPuaFT3TFjOhSibUAso0odbOaCDj3Q==",
|
||||
"path": "microsoft.extensions.primitives/7.0.0",
|
||||
"hashPath": "microsoft.extensions.primitives.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Abstractions/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-PT16ZFbPIiMsYv07oy3zOjqUOJ7xutGBkJTOX0+IbNyU6+O6X7aIxjq9EaSSRLWbekRgamgtmfg8Xjw6A6Ua9g==",
|
||||
"path": "microsoft.identitymodel.abstractions/7.5.1",
|
||||
"hashPath": "microsoft.identitymodel.abstractions.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.JsonWebTokens/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-93CGSa8RPdZU8zfvA3nf9NGKUqEnQrE12VzYlMqKh72ddhzusosqLNEUgH/YhFWBLRFOnY1RCgHMV7pR+sAx2w==",
|
||||
"path": "microsoft.identitymodel.jsonwebtokens/7.5.1",
|
||||
"hashPath": "microsoft.identitymodel.jsonwebtokens.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Logging/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-PnpAQX20BAiDIPYmWUyQSlEaWD8BLXzHpiDGTCT568Cs0ReOeyzNe401LzCeiv6ilug/KefVeV1CeqtCHTo8dw==",
|
||||
"path": "microsoft.identitymodel.logging/7.5.1",
|
||||
"hashPath": "microsoft.identitymodel.logging.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IdentityModel.Tokens/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Q3DKpyFViP84IUlTFKH/zIkswIrmSh2Vd/eFDo4wlOHy4DYxoweZEEw4kDEiKt9VCX6o7SddK3HK2xDYyFpexA==",
|
||||
"path": "microsoft.identitymodel.tokens/7.5.1",
|
||||
"hashPath": "microsoft.identitymodel.tokens.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-2nXPrhdAyAzir0gLl8Yy8S5Mnm/uBSQQA7jEsILOS1MTyS7DbmV1NgViMtvV1sfCD1ebITpNwb1NIinKeJgUVQ==",
|
||||
"path": "microsoft.win32.systemevents/7.0.0",
|
||||
"hashPath": "microsoft.win32.systemevents.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-WvRUdlL1lB0dTRZSs5XcQOd5q9MYNk90GkbmRmiCvRHThWiojkpGqWdmEDJdXyHbxG/BhE5hmVbMfRLXW9FJVA==",
|
||||
"path": "system.configuration.configurationmanager/7.0.0",
|
||||
"hashPath": "system.configuration.configurationmanager.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Diagnostics.EventLog/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-eUDP47obqQm3SFJfP6z+Fx2nJ4KKTQbXB4Q9Uesnzw9SbYdhjyoGXuvDn/gEmFY6N5Z3bFFbpAQGA7m6hrYJCw==",
|
||||
"path": "system.diagnostics.eventlog/7.0.0",
|
||||
"hashPath": "system.diagnostics.eventlog.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.DirectoryServices/7.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Z4FVdUJEVXbf7/f/hU6cFZDtxN5ozUVKJMzXoHmC+GCeTcqzlxqmWtxurejxG3K+kZ6H0UKwNshoK1CYnmJ1sg==",
|
||||
"path": "system.directoryservices/7.0.1",
|
||||
"hashPath": "system.directoryservices.7.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.DirectoryServices.AccountManagement/7.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-UNytHYwA5IF55WQhashsMG57ize83JUGJxD8YJlOyO9ZlMTOD4Nt7y+A6mvmrU/swDoYWaVL+TNwE6hk9lyvbA==",
|
||||
"path": "system.directoryservices.accountmanagement/7.0.1",
|
||||
"hashPath": "system.directoryservices.accountmanagement.7.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.DirectoryServices.Protocols/7.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-t9hsL+UYRzNs30pnT2Tdx6ngX8McFUjru0a0ekNgu/YXfkXN+dx5OvSEv0/p7H2q3pdJLH7TJPWX7e55J8QB9A==",
|
||||
"path": "system.directoryservices.protocols/7.0.1",
|
||||
"hashPath": "system.directoryservices.protocols.7.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.Drawing.Common/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-KIX+oBU38pxkKPxvLcLfIkOV5Ien8ReN78wro7OF5/erwcmortzeFx+iBswlh2Vz6gVne0khocQudGwaO1Ey6A==",
|
||||
"path": "system.drawing.common/7.0.0",
|
||||
"hashPath": "system.drawing.common.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt/7.5.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-UUw+E0R73lZLlXgneYIJQxNs1kfbcxjVzw64JQyiwjqCd4HMpAbjn+xRo86QZT84uHq8/MkqvfH82tgjgPzpuw==",
|
||||
"path": "system.identitymodel.tokens.jwt/7.5.1",
|
||||
"hashPath": "system.identitymodel.tokens.jwt.7.5.1.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-xSPiLNlHT6wAHtugASbKAJwV5GVqQK351crnILAucUioFqqieDN79evO1rku1ckt/GfjIn+b17UaSskoY03JuA==",
|
||||
"path": "system.security.cryptography.protecteddata/7.0.0",
|
||||
"hashPath": "system.security.cryptography.protecteddata.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Permissions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Vmp0iRmCEno9BWiskOW5pxJ3d9n+jUqKxvX4GhLwFhnQaySZmBN2FuC0N5gjFHgyFMUjC5sfIJ8KZfoJwkcMmA==",
|
||||
"path": "system.security.permissions/7.0.0",
|
||||
"hashPath": "system.security.permissions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Windows.Extensions/7.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-bR4qdCmssMMbo9Fatci49An5B1UaVJZHKNq70PRgzoLYIlitb8Tj7ns/Xt5Pz1CkERiTjcVBDU2y1AVrPBYkaw==",
|
||||
"path": "system.windows.extensions/7.0.0",
|
||||
"hashPath": "system.windows.extensions.7.0.0.nupkg.sha512"
|
||||
},
|
||||
"WebCore.Contracts/1.0.1": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"DigitalData.Core.Contracts/1.0.1.0": {
|
||||
"type": "reference",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 22 KiB |
@@ -1,4 +0,0 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v7.0", FrameworkDisplayName = ".NET 7.0")]
|
||||
@@ -1,8 +0,0 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
@@ -1,170 +0,0 @@
|
||||
{
|
||||
"format": 1,
|
||||
"restore": {
|
||||
"E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.CultureServices\\DigitalData.Core.CultureServices.csproj": {}
|
||||
},
|
||||
"projects": {
|
||||
"E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj": {
|
||||
"version": "1.0.1",
|
||||
"restore": {
|
||||
"projectUniqueName": "E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj",
|
||||
"projectName": "WebCore.Contracts",
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj",
|
||||
"packagesPath": "C:\\Users\\tekh\\.nuget\\packages\\",
|
||||
"outputPath": "E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.Contracts\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\Offline Packages"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\tekh\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 21.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net7.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\System\\Components\\Packages": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Caching.Memory": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.0, )"
|
||||
},
|
||||
"Microsoft.Extensions.Configuration.Binder": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.4, )"
|
||||
},
|
||||
"System.DirectoryServices": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.1, )"
|
||||
},
|
||||
"System.DirectoryServices.AccountManagement": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.1, )"
|
||||
},
|
||||
"System.IdentityModel.Tokens.Jwt": {
|
||||
"target": "Package",
|
||||
"version": "[7.5.1, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.200\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.CultureServices\\DigitalData.Core.CultureServices.csproj": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.CultureServices\\DigitalData.Core.CultureServices.csproj",
|
||||
"projectName": "DigitalData.Core.CultureServices",
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.CultureServices\\DigitalData.Core.CultureServices.csproj",
|
||||
"packagesPath": "C:\\Users\\tekh\\.nuget\\packages\\",
|
||||
"outputPath": "E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.CultureServices\\obj\\",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\Offline Packages"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"C:\\Users\\tekh\\AppData\\Roaming\\NuGet\\NuGet.Config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\DevExpress 21.2.config",
|
||||
"C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"net7.0"
|
||||
],
|
||||
"sources": {
|
||||
"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
|
||||
"D:\\ProgramFiles\\DevExpress 21.2\\Components\\System\\Components\\Packages": {},
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"projectReferences": {
|
||||
"E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj": {
|
||||
"projectPath": "E:\\TekH\\Visual Studio\\WebCoreModules\\DigitalData.Core.Contracts\\DigitalData.Core.Contracts.csproj"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
},
|
||||
"restoreAuditProperties": {
|
||||
"enableAudit": "true",
|
||||
"auditLevel": "low",
|
||||
"auditMode": "direct"
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"net7.0": {
|
||||
"targetAlias": "net7.0",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Localization": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.16, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48",
|
||||
"net481"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"frameworkReferences": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"privateAssets": "all"
|
||||
}
|
||||
},
|
||||
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.200\\RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\tekh\.nuget\packages\;D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.9.1</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\tekh\.nuget\packages\" />
|
||||
<SourceRoot Include="D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.1\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.1\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>DigitalData.Core.CultureServices</id>
|
||||
<version>1.0.0</version>
|
||||
<authors>DigitalData.Core.CultureServices</authors>
|
||||
<description>Package Description</description>
|
||||
<repository type="git" commit="82da3586a5e28ae5fbd4242f05f60f9e5327e5f2" />
|
||||
<dependencies>
|
||||
<group targetFramework="net7.0">
|
||||
<dependency id="WebCore.Contracts" version="1.0.1" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Extensions.Localization" version="7.0.16" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\bin\Release\net7.0\DigitalData.Core.CultureServices.dll" target="lib\net7.0\DigitalData.Core.CultureServices.dll" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -1,4 +0,0 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v7.0", FrameworkDisplayName = ".NET 7.0")]
|
||||
@@ -1,13 +0,0 @@
|
||||
is_global = true
|
||||
build_property.TargetFramework = net7.0
|
||||
build_property.TargetPlatformMinVersion =
|
||||
build_property.UsingMicrosoftNETSdkWeb =
|
||||
build_property.ProjectTypeGuids =
|
||||
build_property.InvariantGlobalization =
|
||||
build_property.PlatformNeutralAssembly =
|
||||
build_property.EnforceExtendedAnalyzerRules =
|
||||
build_property._SupportedPlatformList = Linux,macOS,Windows
|
||||
build_property.RootNamespace = DigitalData.Core.CultureServices
|
||||
build_property.ProjectDir = E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\
|
||||
build_property.EnableComHosting =
|
||||
build_property.EnableGeneratedComInterfaceComImportInterop =
|
||||
@@ -1,8 +0,0 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
@@ -1 +0,0 @@
|
||||
36fef0fd26a832d2188715455582d92b1504d333459c8ca9de1908bace5726e0
|
||||
@@ -1,16 +0,0 @@
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\bin\Release\net7.0\DigitalData.Core.CultureServices.deps.json
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\bin\Release\net7.0\DigitalData.Core.CultureServices.dll
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\bin\Release\net7.0\DigitalData.Core.CultureServices.pdb
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\bin\Release\net7.0\DigitalData.Core.Contracts.dll
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\bin\Release\net7.0\DigitalData.Core.Contracts.pdb
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\DigitalData.Core.CultureServices.csproj.AssemblyReference.cache
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\DigitalData.Core.CultureServices.GeneratedMSBuildEditorConfig.editorconfig
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\DigitalData.Core.CultureServices.AssemblyInfoInputs.cache
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\DigitalData.Core.CultureServices.AssemblyInfo.cs
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\DigitalData.Core.CultureServices.csproj.CoreCompileInputs.cache
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\DigitalD.489AA3D4.Up2Date
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\DigitalData.Core.CultureServices.dll
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\refint\DigitalData.Core.CultureServices.dll
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\DigitalData.Core.CultureServices.pdb
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\obj\Release\net7.0\ref\DigitalData.Core.CultureServices.dll
|
||||
E:\TekH\Visual Studio\WebCoreModules\DigitalData.Core.CultureServices\bin\Release\net7.0\icon.png
|
||||
|
Before Width: | Height: | Size: 1020 KiB |
@@ -1,22 +0,0 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
public static class AutoMapperExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// Maps a source object to a destination object, or throws an exception if the mapping result is null.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source object type.</typeparam>
|
||||
/// <typeparam name="TDestination">The destination object type.</typeparam>
|
||||
/// <param name="source">The source object to map from.</param>
|
||||
/// <returns>The mapped destination object.</returns>
|
||||
/// <exception cref="MappingResultNullException">Thrown when the mapping result is null.</exception>
|
||||
public static TDestination MapOrThrow<TDestination>(this IMapper mapper, object source)
|
||||
{
|
||||
return mapper.Map<TDestination>(source) ?? throw new AutoMapperMappingException(
|
||||
$"Mapping to {typeof(TDestination).FullName} resulted in a null object. " +
|
||||
"Hint: Ensure that the AutoMapper profile configuration for this mapping is correct.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,6 +147,35 @@ namespace DigitalData.Core.DTO
|
||||
/// <returns>True if any notice has any of the specified flags; otherwise, false.</returns>
|
||||
public static bool HasAnyFlag(this IEnumerable<Notice> notices, params Enum[] flags) => flags.Any(f => notices.HasFlag(f));
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function based on the success or failure of the task result,
|
||||
/// without using result data.
|
||||
/// </summary>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="tResult">The task returning a result to evaluate.</param>
|
||||
/// <param name="Success">The function to execute if the result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
public static I? Then<I>(this Result result, Func<I> Success)
|
||||
{
|
||||
return result.IsSuccess ? Success() : default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function based on the success or failure of the task result,
|
||||
/// using the data in the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data in the result.</typeparam>
|
||||
/// <typeparam name="I">The type of the return value.</typeparam>
|
||||
/// <param name="tResult">The task returning a data result to evaluate.</param>
|
||||
/// <param name="Success">The function to execute if the data result is successful.</param>
|
||||
/// <param name="Fail">The function to execute if the data result is a failure.</param>
|
||||
/// <returns>The result of the executed function.</returns>
|
||||
public static async Task<I?> ThenAsync<I>(this Result result, Func<Task<I>> SuccessAsync)
|
||||
{
|
||||
return result.IsSuccess ? await SuccessAsync() : default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes a function based on the success or failure of the result.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Description>This package provides Data Transfer Object (DTO) implementations and related utilities. It includes generic result handling, DTO extension methods, cookie consent settings management, and AutoMapper integration for robust object mapping, all adhering to Clean Architecture principles to ensure separation of concerns and maintainability.</Description>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<PackageId>DigitalData.Core.DTO</PackageId>
|
||||
<Version>1.0.0</Version>
|
||||
<Version>2.0.0.0</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.DTO</Product>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core dto clean architecture result pattern</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\DigitalData.Core.Abstractions\Assets\icon.png">
|
||||
<None Include="..\..\nuget-package-icons\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
/// Indicates that either a possible security breach, a possible data integrity issue, or both have been detected during the service operation.
|
||||
/// This flag is used when it is uncertain whether the issue is related to security, data integrity, or both.
|
||||
/// </summary>
|
||||
PossibleSecurityBreachOrDataIntegrity
|
||||
PossibleSecurityBreachOrDataIntegrity,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the requested resource or operation could not be found.
|
||||
/// This flag is used when the specified item or condition does not exist or is unavailable.
|
||||
/// </summary>
|
||||
NotFound
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1020 KiB |
@@ -1,4 +1,5 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DigitalData.Core.Infrastructure
|
||||
@@ -14,7 +15,7 @@ namespace DigitalData.Core.Infrastructure
|
||||
/// It leverages the EF Core's DbContext and DbSet to perform these operations.
|
||||
/// </remarks>
|
||||
public class CRUDRepository<TEntity, TId, TDbContext> : ICRUDRepository<TEntity, TId>
|
||||
where TEntity : class
|
||||
where TEntity : class, IUnique<TId>
|
||||
where TDbContext : DbContext
|
||||
{
|
||||
protected readonly TDbContext _dbContext;
|
||||
@@ -24,10 +25,11 @@ namespace DigitalData.Core.Infrastructure
|
||||
/// Initializes a new instance of the CRUDRepository with the specified DbContext.
|
||||
/// </summary>
|
||||
/// <param name="dbContext">The DbContext instance to be used by the repository.</param>
|
||||
public CRUDRepository(TDbContext dbContext)
|
||||
/// <param name="dbSet">The DbSet instance to be used by the repository.</param>
|
||||
public CRUDRepository(TDbContext dbContext, DbSet<TEntity> dbSet)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_dbSet = dbContext.Set<TEntity>();
|
||||
_dbSet = dbSet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -49,11 +51,21 @@ namespace DigitalData.Core.Infrastructure
|
||||
/// <returns>The entity found, or null if no entity is found with the specified identifier.</returns>
|
||||
public virtual async Task<TEntity?> ReadByIdAsync(TId id) => await _dbSet.FindAsync(id);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all entities of type <typeparamref name="TEntity"/> from the database.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method returns an <see cref="IQueryable{TEntity}"/> of all entities in the database.
|
||||
/// The result is not tracked by the context, which improves performance when you only need to read data without making modifications.
|
||||
/// </remarks>
|
||||
/// <returns>An <see cref="IQueryable{TEntity}"/> containing all entities of type <typeparamref name="TEntity"/>.</returns>
|
||||
protected virtual IQueryable<TEntity> ReadOnly() => _dbSet.AsNoTracking();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves all entities of type TEntity.
|
||||
/// </summary>
|
||||
/// <returns>An enumerable of all entities in the database.</returns>
|
||||
public virtual async Task<IEnumerable<TEntity>> ReadAllAsync() => await _dbSet.ToListAsync();
|
||||
public virtual async Task<IEnumerable<TEntity>> ReadAllAsync() => await ReadOnly().ToListAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously updates an existing entity in the repository.
|
||||
@@ -84,5 +96,17 @@ namespace DigitalData.Core.Infrastructure
|
||||
/// </summary>
|
||||
/// <returns>The total number of entities in the repository.</returns>
|
||||
public virtual async Task<int> CountAsync() => await _dbSet.CountAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously counts the number of entities in the repository that match a specific identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the entities to count.</param>
|
||||
/// <returns>The number of entities with the specified identifier.</returns>
|
||||
/// <remarks>
|
||||
/// This method provides a count of entities in the database that match the given identifier.
|
||||
/// If there are multiple entities with the same identifier, they will all be counted.
|
||||
/// The default implementation assumes that the identifier is unique for each entity.
|
||||
/// </remarks>
|
||||
public virtual async Task<int> CountAsync(TId id) => await _dbSet.Where(e => e.Id!.Equals(id)).CountAsync();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using DigitalData.Core.Abstractions;
|
||||
using DigitalData.Core.Abstractions.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.DirectoryServices;
|
||||
@@ -17,7 +18,7 @@ namespace DigitalData.Core.Infrastructure
|
||||
/// <param name="configureRepository">An optional action to configure additional services for the repository.</param>
|
||||
/// <returns>The original <see cref="IServiceCollection"/> instance, allowing further configuration.</returns>
|
||||
public static IServiceCollection AddCleanCRUDRepository<TEntity, TId, TDbContext, TCRUDRepository>(this IServiceCollection services, Action<IServiceCollection>? configureRepository = null)
|
||||
where TCRUDRepository : CRUDRepository<TEntity, TId, TDbContext> where TEntity : class where TDbContext : DbContext
|
||||
where TCRUDRepository : CRUDRepository<TEntity, TId, TDbContext> where TEntity : class, IUnique<TId> where TDbContext : DbContext
|
||||
{
|
||||
services.AddScoped<ICRUDRepository<TEntity, TId>, TCRUDRepository>();
|
||||
configureRepository?.Invoke(services);
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<PackageId>DigitalData.Core.Infrastructure</PackageId>
|
||||
<Version>1.0.1.1</Version>
|
||||
<Version>2.0.0.0</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.Infrastructure</Product>
|
||||
<Description>This package provides implementations for data access and other low-level services within the DigitalData.Core.Abstractions library. It includes generic CRUD operations using Entity Framework Core, database context management, and other infrastructure-related functionalities, adhering to Clean Architecture principles to ensure separation of concerns and maintainability.</Description>
|
||||
<Copyright>Copyright 2024</Copyright>
|
||||
<PackageIcon>icon.png</PackageIcon>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<RepositoryType>digital data core abstractions clean architecture</RepositoryType>
|
||||
<PackageTags>digital data core infrastructure clean architecture</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="..\DigitalData.Core.Abstractions\Assets\icon.png">
|
||||
<None Include="..\..\nuget-package-icons\core_icon.png">
|
||||
<Pack>True</Pack>
|
||||
<PackagePath>\</PackagePath>
|
||||
</None>
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
<SourceRoot Include="C:\Users\tekh\.nuget\packages\" />
|
||||
<SourceRoot Include="D:\ProgramFiles\DevExpress 21.2\Components\Offline Packages\" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<ImportGroup Condition=" '$(TargetFramework)' == 'net7.0' AND '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.16\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.16\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props')" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition=" '$(TargetFramework)' == 'net8.0' AND '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.16\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.16\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<ImportGroup Condition=" '$(TargetFramework)' == 'net7.0' AND '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition=" '$(TargetFramework)' == 'net8.0' AND '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
BIN
DigitalData.Core.Legacy.Client/Assets/icon.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
@@ -12,7 +12,7 @@ namespace DigitalData.Core.Legacy.Client
|
||||
protected readonly HttpClient _client;
|
||||
protected readonly CookieContainer _cookies;
|
||||
|
||||
public string Uri { get; }
|
||||
public string Uri { get; protected set; }
|
||||
|
||||
public BaseHttpClientService(HttpClient client, CookieContainer cookieContainer, IOptions<HttpClientOptions> clientOptions)
|
||||
{
|
||||
@@ -30,6 +30,10 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>
|
||||
</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
@@ -91,5 +95,10 @@
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\icon.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package>
|
||||
<metadata>
|
||||
<id>DigitalData.Core.Client.Legacy</id>
|
||||
<version>1.0.1.2</version>
|
||||
<authors>Digital Data GmbH</authors>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<icon>Assets\icon.png</icon>
|
||||
<projectUrl>http://git.dd:3000/AppStd/WebCoreModules.git</projectUrl>
|
||||
<description>This package provides HTTP client extension methods for the DigitalData.Core library, offering simplified and asynchronous methods for fetching and handling HTTP responses. It includes utility methods for sending GET, POST, PUT, DELETE requests, reading response content as text or JSON, and deserializing JSON into dynamic or strongly-typed objects using Newtonsoft.Json. These extensions facilitate efficient and easy-to-read HTTP interactions in client applications. This version is specifically designed to be compatible with .NET Framework.</description>
|
||||
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
|
||||
<copyright>Copyright 2024</copyright>
|
||||
<tags>digital data core http client json serialization</tags>
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" />
|
||||
<dependency id="Microsoft.Extensions.DependencyInjection" version="8.0.0" />
|
||||
<dependency id="Microsoft.Extensions.DependencyInjection.Abstractions" version="8.0.0" />
|
||||
<dependency id="Microsoft.Extensions.Options" version="8.0.2" />
|
||||
<dependency id="Microsoft.Extensions.Primitives" version="8.0.0" />
|
||||
<dependency id="Newtonsoft.Json" version="13.0.0" />
|
||||
<dependency id="System.Buffers" version="4.0.3" />
|
||||
<dependency id="System.Memory" version="4.0.1" />
|
||||
<dependency id="System.Numerics.Vectors" version="4.1.4" />
|
||||
<dependency id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" />
|
||||
<dependency id="System.Threading.Tasks.Extensions" version="4.2.0" />
|
||||
<dependency id="System.ValueTuple" version="4.0.3" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="bin\Release\DigitalData.Core.Client.Legacy.dll" target="lib\net462\" />
|
||||
<file src="..\icon.png" target="Assets\" />
|
||||
</files>
|
||||
</package>
|
||||
@@ -4,7 +4,7 @@ using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DigitalData.Core.Legacy
|
||||
namespace DigitalData.Core.Legacy.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for HttpClient and HttpResponseMessage.
|
||||
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("DigitalData.Core.Legacy.Client")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyDescription("This package provides HTTP client extension methods for the DigitalData.Core.Legacy library, offering simplified and asynchronous methods for fetching and handling HTTP responses. It includes utility methods for sending GET requests, reading response content as text or JSON, and deserializing JSON into dynamic or strongly-typed objects using Newtonsoft.Json. These extensions facilitate efficient and easy-to-read HTTP interactions in client applications running on legacy .NET Framework platforms.")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Digital Data GmbH")]
|
||||
[assembly: AssemblyProduct("DigitalData.Core.Legacy.Client")]
|
||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyVersion("1.0.1.1")]
|
||||
[assembly: AssemblyFileVersion("1.0.1.1")]
|
||||
@@ -7,6 +7,7 @@
|
||||
<package id="Microsoft.Extensions.Options" version="8.0.2" targetFramework="net462" />
|
||||
<package id="Microsoft.Extensions.Primitives" version="8.0.0" targetFramework="net462" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net462" />
|
||||
<package id="NuGet.CommandLine" version="6.10.1" targetFramework="net462" developmentDependency="true" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net462" />
|
||||
<package id="System.Memory" version="4.5.5" targetFramework="net462" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net462" />
|
||||
@@ -87,9 +87,8 @@
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.Client.Legacy\DigitalData.Core.Legacy.Client.csproj">
|
||||
<ProjectReference Include="..\DigitalData.Core.Legacy.Client\DigitalData.Core.Legacy.Client.csproj">
|
||||
<Project>{e009a053-a9f4-48f2-984f-ef5c376a9b14}</Project>
|
||||
<Name>DigitalData.Core.Legacy.Client</Name>
|
||||
</ProjectReference>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.Abstractions\DigitalData.Core.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
13
DigitalData.Core.Security.Extensions/Extensions.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace DigitalData.Core.Security.Extensions
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static string ToBase64String(this byte[] bytes) => Convert.ToBase64String(bytes);
|
||||
|
||||
public static byte[] Base64ToByte(this string base64String) => Convert.FromBase64String(base64String);
|
||||
|
||||
public static byte[] ToBytes(this string str) => System.Text.Encoding.UTF8.GetBytes(str);
|
||||
|
||||
public static string BytesToString(this byte[] bytes) => System.Text.Encoding.UTF8.GetString(bytes);
|
||||
}
|
||||
}
|
||||
60
DigitalData.Core.Security.Extensions/RSAExtensions.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace DigitalData.Core.Security.Extensions
|
||||
{
|
||||
public static class RSAExtensions
|
||||
{
|
||||
public static RSA ToRSA(this string pem)
|
||||
{
|
||||
var rsa = RSA.Create();
|
||||
rsa.ImportFromPem(pem);
|
||||
return rsa;
|
||||
}
|
||||
|
||||
private static string CreatePath(string filename, string? directory = null)
|
||||
{
|
||||
directory ??= Environment.CurrentDirectory;
|
||||
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
return Path.Combine(directory, $"{filename}.pem");
|
||||
}
|
||||
|
||||
private static readonly ConcurrentDictionary<string, SemaphoreSlim> FileLocks = new();
|
||||
|
||||
public static void SavePem(this IRSACryptographer decryptor, string key, string? directory = null)
|
||||
{
|
||||
var filePath = CreatePath(filename: key, directory : directory);
|
||||
var fileLock = FileLocks.GetOrAdd(filePath, _ => new (1, 1));
|
||||
fileLock.Wait();
|
||||
try
|
||||
{
|
||||
File.WriteAllText(filePath, decryptor.Pem);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fileLock.Release();
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task SavePemAsync(this IRSACryptographer decryptor, string key, string? directory = null)
|
||||
{
|
||||
var filePath = CreatePath(filename: key, directory: directory);
|
||||
var fileLock = FileLocks.GetOrAdd(filePath, _ => new (1, 1));
|
||||
await fileLock.WaitAsync();
|
||||
try
|
||||
{
|
||||
await File.WriteAllTextAsync(filePath, decryptor.Pem);
|
||||
}
|
||||
finally
|
||||
{
|
||||
fileLock.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
20
DigitalData.Core.Security/AsymCryptService.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.Config;
|
||||
using DigitalData.Core.Security.Cryptographer;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public class AsymCryptService<TAsymCryptParams> : RSAFactory<TAsymCryptParams>, IAsymCryptService<TAsymCryptParams>, IRSAFactory<TAsymCryptParams> where TAsymCryptParams : AsymCryptParams
|
||||
{
|
||||
public IEnumerable<IRSADecryptor> Decryptors => _params.Decryptors;
|
||||
|
||||
public IEnumerable<IRSAEncryptor> Encryptors => _params.Encryptors;
|
||||
|
||||
public AsymCryptService(IOptions<TAsymCryptParams> options, ILogger<AsymCryptService<TAsymCryptParams>>? logger = null) : base(options)
|
||||
{
|
||||
logger?.LogInformation("Core.Secrets version: {Version}, Created on: {CreationDate}.", Secrets.Version, Secrets.CreationDate.ToString("dd.MM.yyyy"));
|
||||
}
|
||||
}
|
||||
}
|
||||
59
DigitalData.Core.Security/Config/AsymCryptParams.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
|
||||
namespace DigitalData.Core.Security.Config
|
||||
{
|
||||
public class AsymCryptParams : RSAFactoryParams
|
||||
{
|
||||
public string Directory { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// 0: Issuer - 1: Audience - 2: Type tag - 3: Version
|
||||
/// </summary>
|
||||
public string FileNameFormat { get; init; } = "{0}_-_{1}_-_{2}_-_{3}.pem";
|
||||
|
||||
public string EncryptorTag { get; init; } = "public";
|
||||
|
||||
public string DecryptorTag { get; init; } = "private";
|
||||
|
||||
public string EncryptedDecryptorTag { get; init; } = "enc-private";
|
||||
|
||||
public IEnumerable<IRSADecryptor> Decryptors { get; init; } = new List<IRSADecryptor>();
|
||||
|
||||
public IEnumerable<IRSAEncryptor> Encryptors { get; init; } = new List<IRSAEncryptor>();
|
||||
|
||||
private string TypeTagOf(IRSACryptographer crypt)
|
||||
{
|
||||
if (crypt is IRSAEncryptor)
|
||||
return EncryptorTag;
|
||||
else if (crypt is IRSADecryptor decryptor)
|
||||
return decryptor.Encrypt ? EncryptedDecryptorTag : DecryptorTag;
|
||||
else
|
||||
throw new InvalidOperationException(
|
||||
"Unknown cryptographer type. The crypt parameter must be either IRSAEncryptor or IRSADecryptor.");
|
||||
}
|
||||
|
||||
public override void OnDeserialized()
|
||||
{
|
||||
base.OnDeserialized();
|
||||
|
||||
var cryptographers = Encryptors.Cast<IRSACryptographer>().Concat(Decryptors.Cast<IRSACryptographer>());
|
||||
|
||||
foreach (var crypt in cryptographers)
|
||||
{
|
||||
// set default path
|
||||
if (crypt.Pem is null)
|
||||
{
|
||||
crypt.Directory ??= Directory;
|
||||
crypt.FileName ??= string.Format(
|
||||
FileNameFormat,
|
||||
crypt.Issuer,
|
||||
crypt.Audience,
|
||||
TypeTagOf(crypt),
|
||||
Secrets.Version);
|
||||
}
|
||||
|
||||
crypt.Init();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
DigitalData.Core.Security/Config/RSAFactoryParams.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DigitalData.Core.Security.Config
|
||||
{
|
||||
public class RSAFactoryParams : IJsonOnDeserialized
|
||||
{
|
||||
public int KeySizeInBits { get; init; } = 2048;
|
||||
|
||||
public string PbePassword { internal get; init; } = Secrets.PBE_PASSWORD;
|
||||
|
||||
public PbeEncryptionAlgorithm PbeEncryptionAlgorithm { get; init; } = PbeEncryptionAlgorithm.Aes256Cbc;
|
||||
|
||||
public HashAlgorithmName PbeHashAlgorithmName { get; init; } = HashAlgorithmName.SHA256;
|
||||
|
||||
public int PbeIterationCount { get; init; } = 100_000;
|
||||
|
||||
public string EncryptedPrivateKeyPemLabel { get; init; } = "ENCRYPTED PRIVATE KEY";
|
||||
|
||||
private PbeParameters? _pbeParameters;
|
||||
|
||||
[JsonIgnore]
|
||||
public PbeParameters PbeParameters => _pbeParameters!;
|
||||
|
||||
public virtual void OnDeserialized() => _pbeParameters = new PbeParameters(PbeEncryptionAlgorithm, PbeHashAlgorithmName, PbeIterationCount);
|
||||
}
|
||||
}
|
||||