Deprecate controllers/services; simplify generics

Added `[Obsolete("Use MediatR")]` attributes to various controller and service classes to indicate deprecation in favor of MediatR. Simplified generic type constraints in `CRUDControllerBase` and related files by removing `IUnique<TId>`. Improved structure and documentation in `CSPMiddleware.cs`. Introduced new extension methods in `EntityExtensions.cs` for safer retrieval of 'Id' properties. Removed `IUnique.cs` interface and updated project dependencies in `DigitalData.Core.Application.csproj` for caching. Overall, these changes enhance code maintainability and clarity.
This commit is contained in:
Developer 02 2025-05-16 14:54:31 +02:00
parent e0c1b856ad
commit 55eb250d7e
18 changed files with 298 additions and 212 deletions

View File

@ -1,4 +1,3 @@
using DigitalData.Core.Abstractions;
using DigitalData.Core.Application.Interfaces; using DigitalData.Core.Application.Interfaces;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
@ -6,10 +5,11 @@ namespace DigitalData.Core.API
{ {
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
[Obsolete("Use MediatR")]
public class BasicCRUDControllerBase<TCRUDService, TDto, TEntity, TId> : CRUDControllerBase<TCRUDService, TDto, TDto, TDto, TEntity, TId> public class BasicCRUDControllerBase<TCRUDService, TDto, TEntity, TId> : CRUDControllerBase<TCRUDService, TDto, TDto, TDto, TEntity, TId>
where TCRUDService : ICRUDService<TDto, TDto, TEntity, TId> where TCRUDService : ICRUDService<TDto, TDto, TEntity, TId>
where TDto : class, IUnique<TId> where TDto : class
where TEntity : class, IUnique<TId> where TEntity : class
{ {
public BasicCRUDControllerBase(ILogger logger, TCRUDService service) : base(logger, service) public BasicCRUDControllerBase(ILogger logger, TCRUDService service) : base(logger, service)
{ {

View File

@ -1,4 +1,3 @@
using DigitalData.Core.Abstractions;
using DigitalData.Core.Application.Interfaces; using DigitalData.Core.Application.Interfaces;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Application.DTO; using DigitalData.Core.Application.DTO;
@ -15,12 +14,13 @@ namespace DigitalData.Core.API
/// <typeparam name="TId">The type of the entity's identifier.</typeparam> /// <typeparam name="TId">The type of the entity's identifier.</typeparam>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
[Obsolete("Use MediatR")]
public class CRUDControllerBase<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase public class CRUDControllerBase<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TEntity, TId> where TCRUDService : ICRUDService<TCreateDto, TReadDto, TEntity, TId>
where TCreateDto : class where TCreateDto : class
where TReadDto : class where TReadDto : class
where TUpdateDto : class, IUnique<TId> where TUpdateDto : class
where TEntity : class, IUnique<TId> where TEntity : class
{ {
protected readonly ILogger _logger; protected readonly ILogger _logger;
protected readonly TCRUDService _service; protected readonly TCRUDService _service;

View File

@ -1,4 +1,3 @@
using DigitalData.Core.Abstractions;
using DigitalData.Core.Application.Interfaces; using DigitalData.Core.Application.Interfaces;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using DigitalData.Core.Application.DTO; using DigitalData.Core.Application.DTO;
@ -16,12 +15,13 @@ namespace DigitalData.Core.API
/// <typeparam name="TId">The type of the entity's identifier.</typeparam> /// <typeparam name="TId">The type of the entity's identifier.</typeparam>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
[Obsolete("Use MediatR")]
public class CRUDControllerBaseWithErrorHandling<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase public class CRUDControllerBaseWithErrorHandling<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TEntity, TId> where TCRUDService : ICRUDService<TCreateDto, TReadDto, TEntity, TId>
where TCreateDto : class where TCreateDto : class
where TReadDto : class where TReadDto : class
where TUpdateDto : class, IUnique<TId> where TUpdateDto : class
where TEntity : class, IUnique<TId> where TEntity : class
{ {
protected readonly ILogger _logger; protected readonly ILogger _logger;
protected readonly TCRUDService _service; protected readonly TCRUDService _service;

View File

@ -1,5 +1,5 @@
namespace DigitalData.Core.API namespace DigitalData.Core.API;
{
/// <summary> /// <summary>
/// Middleware to add Content Security Policy (CSP) headers to the HTTP response. /// Middleware to add Content Security Policy (CSP) headers to the HTTP response.
/// </summary> /// </summary>
@ -35,7 +35,7 @@
// Add the CSP header to the response // Add the CSP header to the response
context.Response.OnStarting(() => context.Response.OnStarting(() =>
{ {
context.Response.Headers.Add("Content-Security-Policy", context.Response.Headers.Append("Content-Security-Policy",
string.Format(_policy, nonce)); string.Format(_policy, nonce));
return Task.CompletedTask; return Task.CompletedTask;
}); });
@ -44,4 +44,3 @@
await _next(context); await _next(context);
} }
} }
}

View File

@ -12,6 +12,7 @@ namespace DigitalData.Core.API
/// <typeparam name="TId">The type of the entity's identifier.</typeparam> /// <typeparam name="TId">The type of the entity's identifier.</typeparam>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
[Obsolete("Use MediatR")]
public class ReadControllerBase<TReadService, TReadDto, TEntity, TId> : ControllerBase public class ReadControllerBase<TReadService, TReadDto, TEntity, TId> : ControllerBase
where TReadService : IReadService<TReadDto, TEntity, TId> where TReadService : IReadService<TReadDto, TEntity, TId>
where TReadDto : class where TReadDto : class

View File

@ -13,6 +13,7 @@ namespace DigitalData.Core.API
/// <typeparam name="TId">The type of the entity's identifier.</typeparam> /// <typeparam name="TId">The type of the entity's identifier.</typeparam>
[ApiController] [ApiController]
[Route("api/[controller]")] [Route("api/[controller]")]
[Obsolete("Use MediatR")]
public class ReadControllerBaseWithErrorHandling<TReadService, TReadDto, TEntity, TId> : ControllerBase public class ReadControllerBaseWithErrorHandling<TReadService, TReadDto, TEntity, TId> : ControllerBase
where TReadService : IReadService<TReadDto, TEntity, TId> where TReadService : IReadService<TReadDto, TEntity, TId>
where TReadDto : class where TReadDto : class

View File

@ -1,7 +0,0 @@
namespace DigitalData.Core.Abstractions
{
public interface IUnique<T>
{
public T Id { get; }
}
}

View File

@ -1,5 +1,4 @@
using AutoMapper; using AutoMapper;
using DigitalData.Core.Abstractions;
using DigitalData.Core.Application.Interfaces; using DigitalData.Core.Application.Interfaces;
using DigitalData.Core.Application.Interfaces.Repository; using DigitalData.Core.Application.Interfaces.Repository;
@ -18,9 +17,10 @@ namespace DigitalData.Core.Application
/// reducing the need for multiple DTOs and simplifying the data mapping process. It leverages AutoMapper for object mapping /// reducing the need for multiple DTOs and simplifying the data mapping process. It leverages AutoMapper for object mapping
/// and a culture-specific translation service for any necessary text translations, ensuring a versatile and internationalized approach to CRUD operations. /// and a culture-specific translation service for any necessary text translations, ensuring a versatile and internationalized approach to CRUD operations.
/// </remarks> /// </remarks>
[Obsolete("Use MediatR")]
public class BasicCRUDService<TCRUDRepository, TDto, TEntity, TId> : public class BasicCRUDService<TCRUDRepository, TDto, TEntity, TId> :
CRUDService<TCRUDRepository, TDto, TDto, TEntity, TId>, IBasicCRUDService<TDto, TEntity, TId> CRUDService<TCRUDRepository, TDto, TDto, TEntity, TId>, IBasicCRUDService<TDto, TEntity, TId>
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId> where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class where TEntity : class
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the BasicCRUDService with the specified repository, translation service, and AutoMapper configuration. /// Initializes a new instance of the BasicCRUDService with the specified repository, translation service, and AutoMapper configuration.

View File

@ -1,5 +1,4 @@
using AutoMapper; using AutoMapper;
using DigitalData.Core.Abstractions;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using DigitalData.Core.Application.Interfaces.Repository; using DigitalData.Core.Application.Interfaces.Repository;
using DigitalData.Core.Application.Interfaces; using DigitalData.Core.Application.Interfaces;
@ -14,8 +13,10 @@ namespace DigitalData.Core.Application
/// <typeparam name="TReadDto">The DTO type for read operations.</typeparam> /// <typeparam name="TReadDto">The DTO type for read operations.</typeparam>
/// <typeparam name="TEntity">The entity type.</typeparam> /// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam> /// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
///
[Obsolete("Use MediatR")]
public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TEntity, TId> : ReadService<TCRUDRepository, TReadDto, TEntity, TId>, ICRUDService<TCreateDto, TReadDto, TEntity, TId> public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TEntity, TId> : ReadService<TCRUDRepository, TReadDto, TEntity, TId>, ICRUDService<TCreateDto, TReadDto, TEntity, TId>
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TEntity : class, IUnique<TId> where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TEntity : class
{ {
/// <summary> /// <summary>
@ -36,7 +37,7 @@ namespace DigitalData.Core.Application
{ {
var entity = _mapper.Map<TEntity>(createDto); var entity = _mapper.Map<TEntity>(createDto);
var createdEntity = await _repository.CreateAsync(entity); var createdEntity = await _repository.CreateAsync(entity);
return createdEntity is null ? Result.Fail<TId>() : Result.Success(createdEntity.Id); return createdEntity is null ? Result.Fail<TId>() : Result.Success(createdEntity.GetIdOrDefault<TId>());
} }
/// <summary> /// <summary>
@ -44,12 +45,12 @@ namespace DigitalData.Core.Application
/// </summary> /// </summary>
/// <param name="updateDto">The DTO to update an entity from.</param> /// <param name="updateDto">The DTO to update an entity from.</param>
/// <returns>A service message indicating success or failure.</returns> /// <returns>A service message indicating success or failure.</returns>
public virtual async Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto) where TUpdateDto : IUnique<TId> public virtual async Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto)
{ {
var currentEntitiy = await _repository.ReadByIdAsync(updateDto.Id); var currentEntitiy = await _repository.ReadByIdAsync(updateDto.GetIdOrDefault<TId>());
if (currentEntitiy is null) if (currentEntitiy is null)
return Result.Fail().Notice(LogLevel.Warning, Flag.NotFound, $"{updateDto.Id} is not found in update process of {GetType()} entity."); return Result.Fail().Notice(LogLevel.Warning, Flag.NotFound, $"{updateDto.GetIdOrDefault<TId>()} is not found in update process of {GetType()} entity.");
var entity = _mapper.Map(updateDto, currentEntitiy); var entity = _mapper.Map(updateDto, currentEntitiy);

View File

@ -27,7 +27,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" /> <PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.16" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
@ -39,18 +38,20 @@
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'"> <ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="AutoMapper" Version="13.0.1" /> <PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="7.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'"> <ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="AutoMapper" Version="14.0.0" /> <PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'"> <ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="AutoMapper" Version="14.0.0" /> <PackageReference Include="AutoMapper" Version="14.0.0" />
</ItemGroup> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="9.0.5" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="9.0.5" />
<ItemGroup>
<ProjectReference Include="..\DigitalData.Core.Abstractions\DigitalData.Core.Abstractions.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,94 @@
namespace DigitalData.Core.Application;
/// <summary>
/// Provides extension methods for retrieving the value of an 'Id' property from objects.
/// </summary>
public static class EntityExtensions
{
/// <summary>
/// Attempts to retrieve the value of the 'Id' property from the specified object.
/// </summary>
/// <typeparam name="TId">The expected type of the 'Id' property.</typeparam>
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
/// <returns>
/// The value of the 'Id' property if it exists and is of type <typeparamref name="TId"/>; otherwise, <c>default</c>.
/// </returns>
public static TId? GetIdOrDefault<TId>(this object? obj)
{
var prop = obj?.GetType().GetProperty("Id");
return prop is not null && prop.GetValue(obj) is TId id ? id : default;
}
/// <summary>
/// Retrieves the value of the 'Id' property from the specified object, or throws an exception if not found or of the wrong type.
/// </summary>
/// <typeparam name="TId">The expected type of the 'Id' property.</typeparam>
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
/// <returns>The value of the 'Id' property.</returns>
/// <exception cref="InvalidOperationException">
/// Thrown if the object does not have a readable 'Id' property of type <typeparamref name="TId"/>.
/// </exception>
public static TId? GetId<TId>(this object? obj)
=> obj.GetIdOrDefault<TId>()
?? throw new InvalidOperationException($"The object of type '{obj?.GetType().FullName ?? "null"}' does not have a readable 'Id' property of type '{typeof(TId).FullName}'.");
/// <summary>
/// Tries to retrieve the value of the 'Id' property from the specified object.
/// </summary>
/// <typeparam name="TId">The expected type of the 'Id' property.</typeparam>
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
/// <param name="id">When this method returns, contains the value of the 'Id' property if found; otherwise, the default value for the type.</param>
/// <returns>
/// <c>true</c> if the 'Id' property was found and is of type <typeparamref name="TId"/>; otherwise, <c>false</c>.
/// </returns>
public static bool TryGetId<TId>(object? obj, out TId id)
{
#pragma warning disable CS8601
id = obj.GetIdOrDefault<TId>();
#pragma warning restore CS8601
return id is not null;
}
/// <summary>
/// Attempts to retrieve the value of the 'Id' property from the specified object.
/// </summary>
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
/// <returns>
/// The value of the 'Id' property if it exists; otherwise, <c>null</c>.
/// </returns>
public static object? GetIdOrDefault(this object? obj)
{
var prop = obj?.GetType().GetProperty("Id");
return prop?.GetValue(obj);
}
/// <summary>
/// Retrieves the value of the 'Id' property from the specified object, or throws an exception if not found.
/// </summary>
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
/// <returns>The value of the 'Id' property.</returns>
/// <exception cref="InvalidOperationException">
/// Thrown if the object does not have a readable 'Id' property.
/// </exception>
public static object GetId(this object? obj)
=> obj.GetIdOrDefault()
?? throw new InvalidOperationException($"The object of type '{obj?.GetType().FullName ?? "null"}' does not have a readable 'Id' property.");
/// <summary>
/// Tries to retrieve the value of the 'Id' property from the specified object.
/// </summary>
/// <param name="obj">The object from which to retrieve the 'Id' property.</param>
/// <param name="id">
/// When this method returns, contains the value of the 'Id' property if found; otherwise, <c>null</c>.
/// </param>
/// <returns>
/// <c>true</c> if the 'Id' property was found; otherwise, <c>false</c>.
/// </returns>
public static bool TryGetId(object? obj, out object id)
{
#pragma warning disable CS8601
id = obj.GetIdOrDefault();
#pragma warning restore CS8601
return id is not null;
}
}

View File

@ -1,6 +1,4 @@
using DigitalData.Core.Abstractions; namespace DigitalData.Core.Application.Interfaces
namespace DigitalData.Core.Application.Interfaces
{ {
/// <summary> /// <summary>
/// Implements a simplified CRUD service interface that uses a single Data Transfer Object (DTO) type for all CRUD operations, /// Implements a simplified CRUD service interface that uses a single Data Transfer Object (DTO) type for all CRUD operations,
@ -15,8 +13,9 @@ namespace DigitalData.Core.Application.Interfaces
/// This interface is useful for entities that do not require different DTOs for different operations, /// This interface is useful for entities that do not require different DTOs for different operations,
/// allowing for a more concise and maintainable codebase when implementing services for such entities. /// allowing for a more concise and maintainable codebase when implementing services for such entities.
/// </remarks> /// </remarks>
[Obsolete("Use MediatR")]
public interface IBasicCRUDService<TDto, TEntity, TId> : ICRUDService<TDto, TDto, TEntity, TId> public interface IBasicCRUDService<TDto, TEntity, TId> : ICRUDService<TDto, TDto, TEntity, TId>
where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId> where TDto : class where TEntity : class
{ {
} }
} }

View File

@ -1,10 +1,10 @@
using DigitalData.Core.Abstractions; using DigitalData.Core.Application.DTO;
using DigitalData.Core.Application.DTO;
namespace DigitalData.Core.Application.Interfaces namespace DigitalData.Core.Application.Interfaces
{ {
[Obsolete("Use MediatR")]
public interface ICRUDService<TCreateDto, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId> public interface ICRUDService<TCreateDto, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
where TCreateDto : class where TReadDto : class where TEntity : class, IUnique<TId> where TCreateDto : class where TReadDto : class where TEntity : class
{ {
/// <summary> /// <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}"/>. /// 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}"/>.
@ -21,6 +21,6 @@ namespace DigitalData.Core.Application.Interfaces
/// </summary> /// </summary>
/// <param name="updateDto">The updateDTO with updated values for the entity.</param> /// <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> /// <returns>An Result indicating the outcome of the update operation, with an appropriate message.</returns>
Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto) where TUpdateDto : IUnique<TId>; Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto);
} }
} }

View File

@ -2,6 +2,7 @@
namespace DigitalData.Core.Application.Interfaces namespace DigitalData.Core.Application.Interfaces
{ {
[Obsolete("Use MediatR")]
public interface IReadService<TReadDto, TEntity, TId> public interface IReadService<TReadDto, TEntity, TId>
where TReadDto : class where TEntity : class where TReadDto : class where TEntity : class
{ {

View File

@ -1,13 +1,11 @@
using DigitalData.Core.Abstractions; namespace DigitalData.Core.Application.Interfaces.Repository
namespace DigitalData.Core.Application.Interfaces.Repository
{ {
/// <summary> /// <summary>
/// Defines the contract for CRUD operations on a repository for entities of type TEntity. /// Defines the contract for CRUD operations on a repository for entities of type TEntity.
/// </summary> /// </summary>
/// <typeparam name="TEntity">The type of the entity this repository works with.</typeparam> /// <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> /// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
public interface ICRUDRepository<TEntity, TId> where TEntity : class, IUnique<TId> public interface ICRUDRepository<TEntity, TId> where TEntity : class
{ {
/// <summary> /// <summary>
/// Adds a new entity to the repository. /// Adds a new entity to the repository.

View File

@ -3,8 +3,8 @@ using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Security.Cryptography; using System.Security.Cryptography;
namespace DigitalData.Core.Application namespace DigitalData.Core.Application;
{
/// <summary> /// <summary>
/// Implements the <see cref="IJWTService{TClaimValue}"/> interface to manage JWT operations for claims of type <typeparamref name="TClaimValue"/>. /// Implements the <see cref="IJWTService{TClaimValue}"/> interface to manage JWT operations for claims of type <typeparamref name="TClaimValue"/>.
/// </summary> /// </summary>
@ -61,4 +61,3 @@ namespace DigitalData.Core.Application
return tokenHandler.CanReadToken(token) ? tokenHandler.ReadToken(token) as JwtSecurityToken : null; return tokenHandler.CanReadToken(token) ? tokenHandler.ReadToken(token) as JwtSecurityToken : null;
} }
} }
}

View File

@ -1,5 +1,6 @@
namespace DigitalData.Core.Application namespace DigitalData.Core.Application;
{
[Obsolete("Use MediatR")]
public static class Key public static class Key
{ {
public static readonly string EntityDoesNotExist = "EntityDoesNotExist"; public static readonly string EntityDoesNotExist = "EntityDoesNotExist";
@ -8,4 +9,3 @@
public static readonly string DeletionFailed = "DeletionFailed"; public static readonly string DeletionFailed = "DeletionFailed";
public static readonly string DirSearcherDisconnected = "DirSearcherDisconnected"; public static readonly string DirSearcherDisconnected = "DirSearcherDisconnected";
} }
}

View File

@ -1,19 +1,19 @@
using AutoMapper; using AutoMapper;
using DigitalData.Core.Abstractions;
using DigitalData.Core.Application.DTO; using DigitalData.Core.Application.DTO;
using DigitalData.Core.Application.Interfaces; using DigitalData.Core.Application.Interfaces;
using DigitalData.Core.Application.Interfaces.Repository; using DigitalData.Core.Application.Interfaces.Repository;
namespace DigitalData.Core.Application namespace DigitalData.Core.Application;
{
/// <summary> /// <summary>
/// Provides generic Read (Read and Delete) operations for a specified type of entity. /// Provides generic Read (Read and Delete) operations for a specified type of entity.
/// </summary> /// </summary>
/// <typeparam name="TReadDto">The DTO type for read operations.</typeparam> /// <typeparam name="TReadDto">The DTO type for read operations.</typeparam>
/// <typeparam name="TEntity">The entity type.</typeparam> /// <typeparam name="TEntity">The entity type.</typeparam>
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam> /// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
[Obsolete("Use MediatR")]
public class ReadService<TCRUDRepository, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId> public class ReadService<TCRUDRepository, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TReadDto : class where TEntity : class, IUnique<TId> where TCRUDRepository : ICRUDRepository<TEntity, TId> where TReadDto : class where TEntity : class
{ {
protected readonly TCRUDRepository _repository; protected readonly TCRUDRepository _repository;
protected readonly IMapper _mapper; protected readonly IMapper _mapper;
@ -76,4 +76,3 @@ namespace DigitalData.Core.Application
/// <returns>A Task that represents the asynchronous operation. The task result contains a boolean value indicating whether the entity exists.</returns> /// <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; public virtual async Task<bool> HasEntity(TId id) => await _repository.CountAsync(id) > 0;
} }
}