Erweiterung der DTOs und Implementierung der Lokalisierungsdienste
- Neue DTO-Extension-Methoden hinzugefügt, um die Verarbeitung und Zuweisung von Nachrichten und Benachrichtigungen in Ergebnisobjekten zu vereinfachen. - Lokalisierungsunterstützung in der API-Schicht implementiert, einschließlich Cookie-basierter Lokalisierung und Konfiguration unterstützter Kulturen. - Die Integration von StringLocalizer in die API-Schicht wurde durchgeführt, um eine nahtlose Mehrsprachigkeit zu ermöglichen. - Fehlerbehandlung für fehlende Konfigurationseinstellungen verbessert. Die Änderungen verbessern die Flexibilität und Wartbarkeit des Codes und unterstützen eine effizientere Internationalisierung der Anwendung.
This commit is contained in:
parent
f6d8721c27
commit
4b71836fea
@ -1,4 +1,5 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.DTO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Text;
|
||||
|
||||
@ -50,10 +51,8 @@ namespace DigitalData.Core.API
|
||||
/// Returns an ObjectResult representing an internal server error (status code 500) with optional exception and message details.
|
||||
/// </summary>
|
||||
/// <param name="controllerBase">The ControllerBase instance representing the controller.</param>
|
||||
/// <param name="ex">Optional. The exception that occurred, if any.</param>
|
||||
/// <param name="message">Optional. A custom error message to include in the response.</param>
|
||||
/// /// <param name="messageKey">Optional. A custom error message key to include in the response.</param>
|
||||
/// <param name="result">Optional. A custom error resul to include in the response.</param>
|
||||
/// <returns>An ObjectResult representing an internal server error (status code 500).</returns>
|
||||
public static ObjectResult InnerServiceError(this ControllerBase controllerBase, IServiceMessage? serviceMessage = null) => controllerBase.StatusCode(500, serviceMessage);
|
||||
public static ObjectResult InnerServiceError(this ControllerBase controllerBase, Result? result = null) => controllerBase.StatusCode(500, result);
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.Contracts\DigitalData.Core.Contracts.csproj" />
|
||||
<ProjectReference Include="..\DigitalData.Core.DTO\DigitalData.Core.DTO.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -20,10 +20,10 @@ namespace DigitalData.Core.API
|
||||
public static IServiceCollection AddCookieBasedLocalizer(this IServiceCollection services, string resourcesPath)
|
||||
{
|
||||
// Adds localization services with the specified resources path.
|
||||
services.AddLocalization(options => options.ResourcesPath = resourcesPath);
|
||||
services.AddLocalization(options => options.ResourcesPath = resourcesPath)
|
||||
|
||||
// Adds MVC services with view localization and data annotations localization.
|
||||
services.AddMvc().AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
|
||||
.AddMvc().AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix)
|
||||
.AddDataAnnotationsLocalization();
|
||||
|
||||
return services;
|
||||
|
||||
@ -4,6 +4,7 @@ using AutoMapper;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using DigitalData.Core.DTO;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
@ -15,26 +16,29 @@ 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> : ServiceBase, ICRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>, IServiceBase
|
||||
public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ICRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : class where TEntity : class
|
||||
{
|
||||
protected readonly TCRUDRepository _repository;
|
||||
protected readonly IMapper _mapper;
|
||||
protected readonly PropertyInfo? _keyPropertyInfo;
|
||||
protected readonly IStringLocalizer _localizer;
|
||||
|
||||
/// <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="translationService">The service for translating messages based on culture.</param>
|
||||
/// <param name="localizer">The localizer for translating messages based on culture.</param>
|
||||
/// <param name="mapper">The AutoMapper instance for mapping between DTOs and entity objects.</param>
|
||||
public CRUDService(TCRUDRepository repository, IStringLocalizer defaultLocalizer, IMapper mapper) : base(defaultLocalizer)
|
||||
public CRUDService(TCRUDRepository repository, IStringLocalizer localizer, IMapper mapper)
|
||||
{
|
||||
_repository = repository;
|
||||
_mapper = mapper;
|
||||
|
||||
_keyPropertyInfo = typeof(TEntity).GetProperties()
|
||||
.FirstOrDefault(prop => Attribute.IsDefined(prop, typeof(KeyAttribute)));
|
||||
|
||||
_localizer = localizer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -42,14 +46,11 @@ namespace DigitalData.Core.Application
|
||||
/// </summary>
|
||||
/// <param name="createDto">The DTO to create an entity from.</param>
|
||||
/// <returns>A service result indicating success or failure, including the entity DTO.</returns>
|
||||
public virtual async Task<IServiceResult<TId>> CreateAsync(TCreateDto createDto)
|
||||
public virtual async Task<DataResult<TId>> CreateAsync(TCreateDto createDto)
|
||||
{
|
||||
var entity = _mapper.MapOrThrow<TEntity>(createDto);
|
||||
var createdEntity = await _repository.CreateAsync(entity);
|
||||
if (createdEntity is null)
|
||||
return Failed<TId>();
|
||||
else
|
||||
return Successful(KeyValueOf(createdEntity));
|
||||
return createdEntity is null ? Result.Fail<TId>() : Result.Success(KeyValueOf(createdEntity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -57,27 +58,23 @@ namespace DigitalData.Core.Application
|
||||
/// </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<IServiceResult<TReadDto>> ReadByIdAsync(TId id)
|
||||
public virtual async Task<DataResult<TReadDto>> ReadByIdAsync(TId id)
|
||||
{
|
||||
var entity = await _repository.ReadByIdAsync(id);
|
||||
if (entity is null)
|
||||
{
|
||||
var translatedMessage = MessageKey.EntityDoesNotExist.LocalizedBy(_localizer);
|
||||
return Failed<TReadDto>();
|
||||
}
|
||||
else
|
||||
return Successful(_mapper.MapOrThrow<TReadDto>(entity));
|
||||
return entity is null
|
||||
? Result.Fail<TReadDto>().Message(_localizer[Key.EntityDoesNotExist])
|
||||
: 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<IServiceResult<IEnumerable<TReadDto>>> ReadAllAsync()
|
||||
public virtual async Task<DataResult<IEnumerable<TReadDto>>> ReadAllAsync()
|
||||
{
|
||||
var entities = await _repository.ReadAllAsync();
|
||||
var readDto = _mapper.MapOrThrow<IEnumerable<TReadDto>>(entities);
|
||||
return Successful(readDto);
|
||||
return Result.Success(readDto);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -85,17 +82,11 @@ namespace DigitalData.Core.Application
|
||||
/// </summary>
|
||||
/// <param name="updateDto">The DTO to update an entity from.</param>
|
||||
/// <returns>A service message indicating success or failure.</returns>
|
||||
public virtual async Task<IServiceMessage> UpdateAsync(TUpdateDto updateDto)
|
||||
public virtual async Task<Result> UpdateAsync(TUpdateDto updateDto)
|
||||
{
|
||||
var entity = _mapper.MapOrThrow<TEntity>(updateDto);
|
||||
bool isUpdated = await _repository.UpdateAsync(entity);
|
||||
if (isUpdated)
|
||||
return Successful();
|
||||
else
|
||||
{
|
||||
var translatedMessage = MessageKey.UpdateFailed.LocalizedBy(_localizer);
|
||||
return Failed();
|
||||
}
|
||||
return isUpdated ? Result.Success() : Result.Fail().Message(_localizer[Key.UpdateFailed]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -103,26 +94,15 @@ namespace DigitalData.Core.Application
|
||||
/// </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<IServiceMessage> DeleteAsyncById(TId id)
|
||||
public virtual async Task<Result> DeleteAsyncById(TId id)
|
||||
{
|
||||
TEntity? entity = await _repository.ReadByIdAsync(id);
|
||||
|
||||
if (entity is null)
|
||||
{
|
||||
var deletionFailedMessage = MessageKey.DeletionFailed.LocalizedBy(_localizer);
|
||||
var entityDoesNotExistMessage = MessageKey.EntityDoesNotExist.LocalizedBy(_localizer);
|
||||
return new ServiceMessage(isSuccess: false, deletionFailedMessage, entityDoesNotExistMessage);
|
||||
}
|
||||
return Result.Fail().Message(_localizer[Key.DeletionFailed], _localizer[Key.EntityDoesNotExist]);
|
||||
|
||||
bool isDeleted = await _repository.DeleteAsync(entity);
|
||||
|
||||
if (isDeleted)
|
||||
return Successful();
|
||||
else
|
||||
{
|
||||
var deletionFailedMessage = MessageKey.DeletionFailed.LocalizedBy(_localizer);
|
||||
return Failed(deletionFailedMessage);
|
||||
}
|
||||
return isDeleted ? Result.Success() : Result.Fail().Message(_localizer[Key.DeletionFailed]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Application.DTO;
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -66,30 +65,9 @@ namespace DigitalData.Core.Application
|
||||
return service;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddResponseService(this IServiceCollection service)
|
||||
{
|
||||
service.AddScoped<IResponseService, ResponseService>();
|
||||
return service;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddJWTService<TClaimValue>(this IServiceCollection services, Func<TClaimValue, SecurityTokenDescriptor> tokenDescriptorFactory)
|
||||
{
|
||||
return services.AddScoped<IJWTService<TClaimValue>, JWTService<TClaimValue>>(provider => new (tokenDescriptorFactory));
|
||||
}
|
||||
|
||||
public static IServiceCollection AddCookieConsentSettings(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<CookieConsentSettings>(sp =>
|
||||
{
|
||||
var configuration = sp.GetRequiredService<IConfiguration>();
|
||||
var settings = configuration.GetSection("CookieConsentSettings").Get<CookieConsentSettings>();
|
||||
if (settings is null)
|
||||
{
|
||||
throw new ConfigurationErrorsException("The 'CookieConsentSettings' section is missing or improperly configured in appsettings.json.");
|
||||
}
|
||||
return settings;
|
||||
});
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,4 +21,8 @@
|
||||
<ProjectReference Include="..\DigitalData.Core.Contracts\DigitalData.Core.Contracts.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="NewFolder\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -6,11 +6,12 @@ using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.DirectoryServices.AccountManagement;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using DigitalData.Core.DTO;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
[SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "<Pending>")]
|
||||
public class DirectorySearchService : ServiceBase, IDirectorySearchService
|
||||
public class DirectorySearchService : IDirectorySearchService
|
||||
{
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
public string ServerName { get; }
|
||||
@ -18,8 +19,9 @@ namespace DigitalData.Core.Application
|
||||
public string SearchRootPath { get; }
|
||||
private readonly DateTimeOffset _userCacheExpiration;
|
||||
public Dictionary<string, string> CustomSearchFilters { get; }
|
||||
protected readonly IStringLocalizer _localizer;
|
||||
|
||||
public DirectorySearchService(IConfiguration configuration, ILogger<DirectorySearchService> logger, IMemoryCache memoryCache, IStringLocalizer defaultLocalizer) : base(defaultLocalizer)
|
||||
public DirectorySearchService(IConfiguration configuration, ILogger<DirectorySearchService> logger, IMemoryCache memoryCache, IStringLocalizer localizer)
|
||||
{
|
||||
_memoryCache = memoryCache;
|
||||
|
||||
@ -37,6 +39,8 @@ namespace DigitalData.Core.Application
|
||||
_userCacheExpiration = default;
|
||||
else
|
||||
_userCacheExpiration = DateTimeOffset.Now.Date.AddDays(dayCounts);
|
||||
|
||||
_localizer = localizer;
|
||||
}
|
||||
|
||||
public bool ValidateCredentials(string dirEntryUsername, string dirEntryPassword)
|
||||
@ -45,7 +49,7 @@ namespace DigitalData.Core.Application
|
||||
return context.ValidateCredentials(dirEntryUsername, dirEntryPassword);
|
||||
}
|
||||
|
||||
public IServiceResult<IEnumerable<ResultPropertyCollection>> FindAll(DirectoryEntry searchRoot, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties)
|
||||
public DataResult<IEnumerable<ResultPropertyCollection>> FindAll(DirectoryEntry searchRoot, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties)
|
||||
{
|
||||
List<ResultPropertyCollection> list = new();
|
||||
|
||||
@ -71,17 +75,17 @@ namespace DigitalData.Core.Application
|
||||
list.Add(rpc);
|
||||
}
|
||||
|
||||
return Successful<IEnumerable<ResultPropertyCollection>>(list);
|
||||
return Result.Success<IEnumerable<ResultPropertyCollection>>(list);
|
||||
}
|
||||
|
||||
public IServiceResult<IEnumerable<ResultPropertyCollection>> FindAllByUserCache(string username, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties)
|
||||
public DataResult<IEnumerable<ResultPropertyCollection>> FindAllByUserCache(string username, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties)
|
||||
{
|
||||
List<ResultPropertyCollection> list = new();
|
||||
|
||||
_memoryCache.TryGetValue(username, out DirectoryEntry? searchRoot);
|
||||
|
||||
if (searchRoot is null)
|
||||
return Failed<IEnumerable<ResultPropertyCollection>>(MessageKey.DirSearcherDisconnected.ToString());
|
||||
return Result.Fail<IEnumerable<ResultPropertyCollection>>().Message(_localizer[Key.DirSearcherDisconnected]);
|
||||
|
||||
return FindAll(searchRoot, filter, searchScope, sizeLimit, properties);
|
||||
}
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for IEnumerable<T>.
|
||||
/// </summary>
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Concatenates the members of a collection, using the specified separator between each member.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the elements of the enumerable.</typeparam>
|
||||
/// <param name="enumerable">The IEnumerable<T> whose elements to concatenate.</param>
|
||||
/// <param name="separator">The string to use as a separator. Separator is included in the returned string only between elements of the collection.</param>
|
||||
/// <returns>A string that consists of the elements in the collection delimited by the separator string. If the collection is empty, the method returns String.Empty.</returns>
|
||||
public static string Join<T>(this IEnumerable<T> enumerable, string separator = ". ") => string.Join(separator, enumerable);
|
||||
}
|
||||
}
|
||||
11
DigitalData.Core.Application/Key.cs
Normal file
11
DigitalData.Core.Application/Key.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
public static class Key
|
||||
{
|
||||
public static readonly string EntityDoesNotExist = "EntityDoesNotExist";
|
||||
public static readonly string ReadFailed = "ReadFailed";
|
||||
public static readonly string UpdateFailed = "UpdateFailed";
|
||||
public static readonly string DeletionFailed = "DeletionFailed";
|
||||
public static readonly string DirSearcherDisconnected = "DirSearcherDisconnected";
|
||||
}
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for ILogger to handle logging of message collections and service messages more effectively.
|
||||
/// </summary>
|
||||
public static class LoggerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Logs a list of messages at the specified log level.
|
||||
/// </summary>
|
||||
/// <param name="logger">The extended ILogger instance.</param>
|
||||
/// <param name="logLevel">The severity level of the log entry.</param>
|
||||
/// <param name="messages">The collection of messages to log.</param>
|
||||
/// <param name="separator">The separator used to join messages. Default is newline.</param>
|
||||
/// <param name="args">Additional arguments used for formatting the log message.</param>
|
||||
public static void LogMessageList(this ILogger logger, LogLevel logLevel, IEnumerable<string> messages, string separator = "\n", params object?[] args)
|
||||
{
|
||||
if (messages.Any())
|
||||
logger.Log(logLevel: logLevel, message: string.Join(separator, messages), args);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs all messages from a service message instance, categorized by message type to appropriate log levels.
|
||||
/// </summary>
|
||||
/// <param name="logger">The extended ILogger instance.</param>
|
||||
/// <param name="serviceMessage">The service message instance containing categorized messages.</param>
|
||||
/// <param name="separator">The separator used to join messages within each category. Default is newline.</param>
|
||||
public static void LogServiceMessage(this ILogger logger, IServiceMessage serviceMessage, string separator = "\n")
|
||||
{
|
||||
logger.LogMessageList(LogLevel.Trace, serviceMessage.TraceMessages, separator);
|
||||
logger.LogMessageList(LogLevel.Debug, serviceMessage.DebugMessages, separator);
|
||||
logger.LogMessageList(LogLevel.Information, serviceMessage.InformationMessages, separator);
|
||||
logger.LogMessageList(LogLevel.Warning, serviceMessage.WarningMessages, separator);
|
||||
logger.LogMessageList(LogLevel.Error, serviceMessage.ErrorMessages, separator);
|
||||
logger.LogMessageList(LogLevel.Critical, serviceMessage.CriticalMessages, separator);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
public enum MessageKey
|
||||
{
|
||||
EntityDoesNotExist,
|
||||
ReadFailed,
|
||||
UpdateFailed,
|
||||
DeletionFailed,
|
||||
DirSearcherDisconnected
|
||||
}
|
||||
}
|
||||
@ -1,211 +0,0 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
public class ResponseService : IResponseService
|
||||
{
|
||||
protected readonly IStringLocalizer _localizer;
|
||||
|
||||
public ResponseService(IStringLocalizer defaultLocalizer)
|
||||
{
|
||||
_localizer = defaultLocalizer;
|
||||
}
|
||||
|
||||
#region WITHOUT_MESSAGE
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service message indicating success or failure without additional messages.
|
||||
/// </summary>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <returns>A service message reflecting the operation outcome.</returns>
|
||||
public IServiceMessage CreateMessage(bool isSuccess = false) => new ServiceMessage()
|
||||
{
|
||||
IsSuccess = isSuccess
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service result containing the provided data and a success flag, without additional messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data included in the result.</typeparam>
|
||||
/// <param name="data">The data to include in the result.</param>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <returns>A service result with the specified data and outcome.</returns>
|
||||
public IServiceResult<T> CreateResult<T>(T? data = default, bool isSuccess = false) => new ServiceResult<T>()
|
||||
{
|
||||
IsSuccess = isSuccess,
|
||||
Data = data
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service message indicating a successful operation without additional messages.
|
||||
/// </summary>
|
||||
/// <returns>A service message indicating a successful operation.</returns>
|
||||
public IServiceMessage Successful() => CreateMessage(true);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service message indicating a failed operation without additional messages.
|
||||
/// </summary>
|
||||
/// <returns>A service message indicating a failed operation.</returns>
|
||||
public IServiceMessage Failed() => CreateMessage(false);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a successful service result with the specified data, without additional messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data included in the result.</typeparam>
|
||||
/// <param name="data">The data to include in the result.</param>
|
||||
/// <returns>A successful service result containing the specified data.</returns>
|
||||
public IServiceResult<T> Successful<T>(T data) => CreateResult(data, true);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a failed service result with optional data, without additional messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result can contain.</typeparam>
|
||||
/// <param name="data">Optional data to include in the result.</param>
|
||||
/// <returns>A failed service result, which may or may not contain the specified data.</returns>
|
||||
public IServiceResult<T> Failed<T>(T? data = default) => CreateResult(data, false);
|
||||
|
||||
#endregion
|
||||
#region WITH_STRING_MESSAGE
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a service message with the specified success flag and messages.
|
||||
/// </summary>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <param name="messages">An array of messages associated with the operation.</param>
|
||||
/// <returns>A new instance of <see cref="ServiceMessage"/> reflecting the operation outcome.</returns>
|
||||
public virtual IServiceMessage CreateMessage(bool isSuccess, params string[] messages) => new ServiceMessage(isSuccess, messages);
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a service result containing the provided data, success flag, and messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data included in the result.</typeparam>
|
||||
/// <param name="data">The data to include in the result.</param>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <param name="messages">An array of messages associated with the operation.</param>
|
||||
/// <returns>A new instance of <see cref="ServiceResult{T}"/> with the specified data and outcome.</returns>
|
||||
public virtual IServiceResult<T> CreateResult<T>(T? data = default, bool isSuccess = true, params string[] messages) => new ServiceResult<T>(data, isSuccess, messages);
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a successful service message.
|
||||
/// </summary>
|
||||
/// <param name="messages">An array of success messages.</param>
|
||||
/// <returns>A successful service message.</returns>
|
||||
public virtual IServiceMessage Successful(params string[] messages) => CreateMessage(true, messages);
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a failed service message.
|
||||
/// </summary>
|
||||
/// <param name="messages">An array of failure messages.</param>
|
||||
/// <returns>A failed service message.</returns>
|
||||
public virtual IServiceMessage Failed(params string[] messages) => CreateMessage(false, messages);
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a successful service result with the provided data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data included in the result.</typeparam>
|
||||
/// <param name="data">The data to include in the result.</param>
|
||||
/// <param name="messages">An array of success messages.</param>
|
||||
/// <returns>A successful service result containing the specified data.</returns>
|
||||
public virtual IServiceResult<T> Successful<T>(T data, params string[] messages) => CreateResult(data, true, messages);
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a failed service result, optionally including data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result can contain.</typeparam>
|
||||
/// <param name="data">Optional data to include in the failed result.</param>
|
||||
/// <param name="messages">An array of failure messages.</param>
|
||||
/// <returns>A failed service result, which may or may not contain the specified data.</returns>
|
||||
public virtual IServiceResult<T> Failed<T>(T? data = default, params string[] messages) => CreateResult(data, false, messages);
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a failed service result using only failure messages, without explicitly including data.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method provides a convenient way to create a failed service result when the failure does not pertain to any specific data,
|
||||
/// or when the inclusion of data is not necessary to convey the failure reason. The data part of the result will be set to its default value.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of data the service result can contain. The result will contain the default value for this type.</typeparam>
|
||||
/// <param name="messages">An array of failure messages that provide details about the reasons for the operation's failure.</param>
|
||||
/// <returns>A failed service result. The data part of the result will be set to the default value for the specified type,
|
||||
/// and it will include the provided failure messages.</returns>
|
||||
public virtual IServiceResult<T> Failed<T>(params string[] messages) => Failed<T>(default, messages);
|
||||
|
||||
#endregion
|
||||
#region WITH_ENUM_MESSAGE
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a service message with the specified success flag and enumeration messages.
|
||||
/// </summary>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <param name="messages">An array of enumeration values associated with the operation.</param>
|
||||
/// <returns>A new instance of <see cref="ServiceMessage"/> reflecting the operation outcome with enumeration messages.</returns>
|
||||
public IServiceMessage CreateMessage(bool isSuccess, params Enum[] messages) => CreateMessage(isSuccess, messages.Select(m => m.ToString()).ToArray());
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a service result containing the provided data, success flag, and enumeration messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data included in the result.</typeparam>
|
||||
/// <param name="data">The data to include in the result.</param>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <param name="messages">An array of enumeration values associated with the operation.</param>
|
||||
/// <returns>A new instance of <see cref="ServiceResult{T}"/> with the specified data and outcome using enumeration messages.</returns>
|
||||
public IServiceResult<T> CreateResult<T>(T? data, bool isSuccess, params Enum[] messages) => CreateResult(data, isSuccess, messages.Select(m => m.ToString()).ToArray());
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a successful service message using enumeration messages.
|
||||
/// </summary>
|
||||
/// <param name="messages">An array of success enumeration values.</param>
|
||||
/// <returns>A successful service message.</returns>
|
||||
public IServiceMessage Successful(params Enum[] messages) => CreateMessage(true, messages.Select(m => m.ToString()).ToArray());
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a failed service message using enumeration messages.
|
||||
/// </summary>
|
||||
/// <param name="messages">An array of failure enumeration values.</param>
|
||||
/// <returns>A failed service message.</returns>
|
||||
public IServiceMessage Failed(params Enum[] messages) => CreateMessage(false, messages.Select(m => m.ToString()).ToArray());
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a successful service result with the provided data using enumeration messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data included in the result.</typeparam>
|
||||
/// <param name="data">The data to include in the result.</param>
|
||||
/// <param name="messages">An array of success enumeration values.</param>
|
||||
/// <returns>A successful service result containing the specified data.</returns>
|
||||
public IServiceResult<T> Successful<T>(T data, params Enum[] messages) => CreateResult(data, true, messages.Select(m => m.ToString()).ToArray());
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a failed service result, optionally including data, using enumeration messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result can contain.</typeparam>
|
||||
/// <param name="data">Optional data to include in the failed result.</param>
|
||||
/// <param name="messages">An array of failure enumeration values.</param>
|
||||
/// <returns>A failed service result, which may or may not contain the specified data.</returns>
|
||||
public IServiceResult<T> Failed<T>(T? data = default, params Enum[] messages) => CreateResult(data, false, messages.Select(m => m.ToString()).ToArray());
|
||||
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// <summary>
|
||||
/// Creates a failed service result using only failure messages, without explicitly including data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result can contain. The result will contain the default value for this type.</typeparam>
|
||||
/// <param name="messages">An array of failure enumeration values that provide details about the reasons for the operation's failure.</param>
|
||||
/// <returns>A failed service result. The data part of the result will be set to the default value for the specified type,
|
||||
/// and it will include the provided failure messages.</returns>
|
||||
public IServiceResult<T> Failed<T>(params Enum[] messages) => Failed<T>(default(T), messages);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
using AutoMapper;
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base implementation of <see cref="IServiceBase"/>.
|
||||
/// </summary>
|
||||
public class ServiceBase : ResponseService, IServiceBase, IResponseService
|
||||
{
|
||||
public ServiceBase(IStringLocalizer defaultLocalizer) : base(defaultLocalizer)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,138 +0,0 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the outcome of a service operation, encapsulating the success or failure status,
|
||||
/// and any associated messages. It also supports optional translation of message keys for localization purposes.
|
||||
/// </summary>
|
||||
public class ServiceMessage : IServiceMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ServiceMessage class.
|
||||
/// </summary>
|
||||
public ServiceMessage()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ServiceMessage class, specifying the success status.
|
||||
/// Optionally, a function for translating message keys can be provided.
|
||||
/// If a translation function is provided, it will be used for both string and enum message keys.
|
||||
/// </summary>
|
||||
/// <param name="isSuccess">Indicates whether the service operation was successful.</param>
|
||||
/// If provided, it will also be adapted for translating enum keys by converting them to strings first.</param>
|
||||
[Obsolete("Deprecated: initialize objects using object initializer.")]
|
||||
public ServiceMessage(bool isSuccess)
|
||||
{
|
||||
IsSuccess = isSuccess;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ServiceMessage class with specified success status, and messages.
|
||||
/// </summary>
|
||||
/// <param name="isSuccess">Indicates whether the service operation was successful.</param>
|
||||
/// <param name="messages">An array of messages related to the operation's outcome.</param>
|
||||
[Obsolete("Deprecated: initialize objects using object initializer.")]
|
||||
public ServiceMessage(bool isSuccess, params string[] messages)
|
||||
{
|
||||
IsSuccess = isSuccess;
|
||||
Messages = messages.ToList<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the service operation was successful.
|
||||
/// </summary>
|
||||
public bool IsSuccess { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the list of flags that indicate specific types of statuses or conditions in a service operation.
|
||||
/// These flags help in categorizing the state of the operation more granularly, allowing for multiple conditions to be represented simultaneously.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<Enum> Flags { get; } = new List<Enum>();
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any of the current service message's flags matches the specified flag based on their string representations.
|
||||
/// This method is useful for conditional logic where the exact string representation of the flag values is crucial.
|
||||
/// </summary>
|
||||
/// <param name="flag">The flag to check against the current service message's flags.</param>
|
||||
/// <returns>true if a flag with a matching string representation exists; otherwise, false.</returns>
|
||||
public bool HasFlag(Enum flag) => Flags.Any(f => f.ToString() == flag.ToString());
|
||||
|
||||
/// <summary>
|
||||
/// [Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// Gets a collection of messages associated with the service operation. These messages can be error descriptions,
|
||||
/// success notifications, or other relevant information related to the operation's outcome.
|
||||
/// </summary>
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
public ICollection<string> Messages { get; init; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages intended for client display. This replaces the deprecated 'Messages' property.
|
||||
/// </summary>
|
||||
public ICollection<string> ClientMessages { get; init; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages used for tracing program execution at a fine-grained level. These are typically voluminous and detailed.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<string> TraceMessages { get; init; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages helpful for debugging during development. These messages are often diagnostic.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<string> DebugMessages { get; init; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of informational messages, less critical than warnings, generally used for non-critical notifications.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<string> InformationMessages { get; init; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages indicating potential issues that are not necessarily errors, but which may require attention.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<string> WarningMessages { get; init; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of error messages indicating failures or problems within the service.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<string> ErrorMessages { get; init; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages indicating critical issues that require immediate attention.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<string> CriticalMessages { get; init; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new message to the collection of messages associated with the service operation.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to add.</param>
|
||||
/// <returns>The current instance of ServiceMessage, allowing for method chaining.</returns>
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
public IServiceMessage WithMessage(string message)
|
||||
{
|
||||
Messages.Add(message);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a message corresponding to the specified message key to the collection of messages associated with the service operation.
|
||||
/// This method uses the string representation of the enum value as the message.
|
||||
/// </summary>
|
||||
/// <param name="messageKey">The enum value representing the message key.</param>
|
||||
/// <returns>The current instance of ServiceMessage, allowing for method chaining.</returns>
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
public IServiceMessage WithMessageKey(Enum messageKey)
|
||||
{
|
||||
Messages.Add(messageKey.ToString());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,153 +0,0 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for IServiceMessage to enhance the usability of service messages
|
||||
/// by allowing easy addition of various types of messages including client, trace, debug, information,
|
||||
/// warning, error, and critical messages. These methods support both direct messages and enum-based keys
|
||||
/// for messages, facilitating localized or custom-formatted messages.
|
||||
/// </summary>
|
||||
public static class ServiceMessageExtensions
|
||||
{
|
||||
#region Flag
|
||||
/// <summary>
|
||||
/// Sets the specified flag on the service message or result, allowing for the categorization of the message based on specific conditions or statuses.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of IServiceMessage.</typeparam>
|
||||
/// <param name="serviceMessage">The service message instance to modify.</param>
|
||||
/// <param name="flag">The flag to set, indicating a specific condition or status.</param>
|
||||
/// <returns>The service message instance with the updated flag, facilitating fluent chaining of methods.</returns>
|
||||
public static T WithFlag<T>(this T serviceMessage, Enum flag) where T : IServiceMessage
|
||||
{
|
||||
serviceMessage.Flags.Add(flag);
|
||||
return serviceMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the service message has a flag indicating a security breach.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message instance to check.</param>
|
||||
/// <returns>True if the service message has the security breach flag; otherwise, false.</returns>
|
||||
public static bool HasSecurityBreachFlag(this IServiceMessage serviceMessage) => serviceMessage.HasFlag(Flag.SecurityBreach);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the service message has a flag indicating a data integrity issue.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message instance to check.</param>
|
||||
/// <returns>True if the service message has the data integrity issue flag; otherwise, false.</returns>
|
||||
public static bool HasDataIntegrityIssueFlag(this IServiceMessage serviceMessage) => serviceMessage.HasFlag(Flag.DataIntegrityIssue);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the service message has a flag indicating either a security breach or a data integrity issue, or both.
|
||||
/// This flag is used when it is not sure whether the problem is security or data integrity. In this case, data integrity should be checked first.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message instance to check.</param>
|
||||
/// <returns>True if the service message has the flag indicating either or both issues; otherwise, false.</returns>
|
||||
public static bool HasSecurityBreachOrDataIntegrityFlag(this IServiceMessage serviceMessage) => serviceMessage.HasFlag(Flag.SecurityBreachOrDataIntegrity);
|
||||
#endregion
|
||||
|
||||
#region StringLocalizer
|
||||
/// <summary>
|
||||
/// Retrieves the localized string for the specified key.
|
||||
/// </summary>
|
||||
/// <param name="key">The key for the localized string.</param>
|
||||
/// <param name="localizer">The localizer to use for retrieving the localized string.</param>
|
||||
/// <returns>The localized string associated with the specified key.</returns>
|
||||
public static string LocalizedBy(this string key, IStringLocalizer localizer) => localizer[key];
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the localized string for the specified enumeration key.
|
||||
/// </summary>
|
||||
/// <param name="key">The enumeration key for the localized string.</param>
|
||||
/// <param name="localizer">The localizer to use for retrieving the localized string.</param>
|
||||
/// <returns>The localized string associated with the specified enumeration key.</returns>
|
||||
public static string LocalizedBy(this Enum key, IStringLocalizer localizer) => localizer[key.ToString()];
|
||||
#endregion
|
||||
|
||||
#region ClientMessage
|
||||
/// <summary>
|
||||
/// Adds a single client message to the service message.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message to modify.</param>
|
||||
/// <param name="message">The message to add.</param>
|
||||
/// <returns>The modified service message instance.</returns>
|
||||
public static T WithClientMessage<T>(this T serviceMessage, string message) where T : IServiceMessage
|
||||
{
|
||||
serviceMessage.ClientMessages.Add(message);
|
||||
return serviceMessage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region TraceMessages
|
||||
/// <summary>
|
||||
/// Adds a trace message to the service message.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message to modify.</param>
|
||||
/// <param name="message">The trace message to add.</param>
|
||||
/// <returns>The modified service message instance.</returns>
|
||||
public static T WithTraceMessage<T>(this T serviceMessage, string message) where T : IServiceMessage
|
||||
{
|
||||
serviceMessage.TraceMessages.Add(message);
|
||||
return serviceMessage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DebugMessages
|
||||
/// <summary>
|
||||
/// Adds a debug message to the service message.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message to modify.</param>
|
||||
/// <param name="message">The debug message to add.</param>
|
||||
/// <returns>The modified service message instance.</returns>
|
||||
public static T WithDebugMessage<T>(this T serviceMessage, string message) where T : IServiceMessage
|
||||
{
|
||||
serviceMessage.DebugMessages.Add(message);
|
||||
return serviceMessage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WarningMessages
|
||||
/// <summary>
|
||||
/// Adds a warning message to the service message.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message to modify.</param>
|
||||
/// <param name="message">The warning message to add.</param>
|
||||
/// <returns>The modified service message instance.</returns>
|
||||
public static T WithWarningMessage<T>(this T serviceMessage, string message) where T : IServiceMessage
|
||||
{
|
||||
serviceMessage.WarningMessages.Add(message);
|
||||
return serviceMessage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ErrorMessages
|
||||
/// <summary>
|
||||
/// Adds an error message to the service message.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message to modify.</param>
|
||||
/// <param name="message">The error message to add.</param>
|
||||
/// <returns>The modified service message instance.</returns>
|
||||
public static T WithErrorMessage<T>(this T serviceMessage, string message) where T : IServiceMessage
|
||||
{
|
||||
serviceMessage.ErrorMessages.Add(message);
|
||||
return serviceMessage;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CriticalMessages
|
||||
/// <summary>
|
||||
/// Adds a critical message to the service message.
|
||||
/// </summary>
|
||||
/// <param name="serviceMessage">The service message to modify.</param>
|
||||
/// <param name="message">The critical message to add.</param>
|
||||
/// <returns>The modified service message instance.</returns>
|
||||
public static T WithCriticalMessage<T>(this T serviceMessage, string message) where T : IServiceMessage
|
||||
{
|
||||
serviceMessage.CriticalMessages.Add(message);
|
||||
return serviceMessage;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
using DigitalData.Core.Contracts.Application;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the outcome of a service operation, encapsulating the success or failure status,
|
||||
/// the data returned by the operation, and any associated messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data returned by the service operation, if any.</typeparam>
|
||||
public class ServiceResult<T> : ServiceMessage, IServiceResult<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ServiceResult class.
|
||||
public ServiceResult()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ServiceResult class, specifying the success status is false and data.
|
||||
/// Optionally, a function for translating message keys can be provided.
|
||||
/// If a translation function is provided, it will be used for both string and enum message keys.
|
||||
/// </summary>
|
||||
/// <param name="data">The data associated with a successful operation.</param>
|
||||
/// <param name="stringKeyTranslator">A function that translates a string key into its localized representation.
|
||||
/// If provided, it will also be adapted for translating enum keys by converting them to strings first.</param>
|
||||
[Obsolete("Deprecated: initialize objects using object initializers instead.")]
|
||||
public ServiceResult(T? data)
|
||||
{
|
||||
Data = data;
|
||||
IsSuccess = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ServiceResult class with specified success status and data.
|
||||
/// </summary>
|
||||
/// <param name="data">The data associated with a successful operation.</param>
|
||||
/// <param name="isSuccess">Indicates whether the service operation was successful.</param>
|
||||
[Obsolete("Deprecated: initialize objects using object initializers instead.")]
|
||||
public ServiceResult(T? data, bool isSuccess) : base(isSuccess) => Data = data;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ServiceResult class with specified success status, data, and messages.
|
||||
/// </summary>
|
||||
/// <param name="data">The data associated with a successful operation.</param>
|
||||
/// <param name="isSuccess">Indicates whether the service operation was successful.</param>
|
||||
/// <param name="messages">An array of messages related to the operation's outcome.</param>
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
public ServiceResult(T? data, bool isSuccess, params string[] messages) : base(isSuccess, messages) => Data = data;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the data resulting from the service operation.
|
||||
/// </summary>
|
||||
public T? Data { get; set; } = default;
|
||||
}
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
namespace DigitalData.Core.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the destination of a message.
|
||||
/// </summary>
|
||||
public enum To
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that the message is intended for the client.
|
||||
/// </summary>
|
||||
Client,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the message is intended for tracing purposes.
|
||||
/// </summary>
|
||||
Trace,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the message is intended for debugging purposes.
|
||||
/// </summary>
|
||||
Debug,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the message is informational.
|
||||
/// </summary>
|
||||
Information,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the message is a warning.
|
||||
/// </summary>
|
||||
Warning,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the message represents an error.
|
||||
/// </summary>
|
||||
Error,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the message represents a critical issue.
|
||||
/// </summary>
|
||||
Critical
|
||||
}
|
||||
}
|
||||
@ -1,58 +1,43 @@
|
||||
using DigitalData.Core.Contracts.Infrastructure;
|
||||
using DigitalData.Core.DTO;
|
||||
|
||||
namespace DigitalData.Core.Contracts.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the contract for CRUD operations at the service level using Data Transfer Objects (DTOs) for entities of type TEntity,
|
||||
/// wrapped in an IServiceResult to encapsulate the outcome of the operation, including success, data, and error messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="TCRUDRepository">The repository type that provides CRUD operations for entities of type TEntity.</typeparam>
|
||||
/// <typeparam name="TCreateDto">The type of the Data Transfer Object this service works with to create new entity.</typeparam>
|
||||
/// <typeparam name="TReadDto">The type of the Data Transfer Object this service works with to read new entity.</typeparam>
|
||||
/// <typeparam name="TUpdateDto">The type of the Data Transfer Object this service works with to update new entity.</typeparam>
|
||||
/// <typeparam name="TEntity">The type of the entity this service maps to.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
public interface ICRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : IServiceBase
|
||||
public interface ICRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : class where TEntity : class
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new entity based on the provided DTO and returns the result wrapped in an IServiceResult,
|
||||
/// including the created entity on success or an error message on failure.
|
||||
/// </summary>
|
||||
/// <param name="createDto">The createDto to create a new entity from.</param>
|
||||
/// <returns>An IServiceResult containing the id of created entity or an error message.</returns>
|
||||
Task<IServiceResult<TId>> CreateAsync(TCreateDto createDto);
|
||||
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 IServiceResult containing the readDTO representing the found entity or null, with an appropriate message.</returns>
|
||||
Task<IServiceResult<TReadDto>> ReadByIdAsync(TId id);
|
||||
/// <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 IServiceResult containing a collection of readDTOs representing all entities or an error message.</returns>
|
||||
Task<IServiceResult<IEnumerable<TReadDto>>> ReadAllAsync();
|
||||
/// <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,
|
||||
/// indicating the success or failure of the operation, including the error messages on failure.
|
||||
/// </summary>
|
||||
/// <param name="updateDto">The updateDTO with updated values for the entity.</param>
|
||||
/// <returns>An IServiceMessage indicating the outcome of the update operation, with an appropriate message.</returns>
|
||||
Task<IServiceMessage> UpdateAsync(TUpdateDto updateDto);
|
||||
/// <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 IServiceMessage indicating the outcome of the delete operation, with an appropriate message.</returns>
|
||||
Task<IServiceMessage> DeleteAsyncById(TId id);
|
||||
/// <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.
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
using System.DirectoryServices;
|
||||
using DigitalData.Core.DTO;
|
||||
using System.DirectoryServices;
|
||||
|
||||
namespace DigitalData.Core.Contracts.Application
|
||||
{
|
||||
public interface IDirectorySearchService : IServiceBase
|
||||
public interface IDirectorySearchService
|
||||
{
|
||||
public string ServerName { get; }
|
||||
|
||||
@ -14,9 +15,9 @@ namespace DigitalData.Core.Contracts.Application
|
||||
|
||||
bool ValidateCredentials(string dirEntryUsername, string dirEntryPassword);
|
||||
|
||||
IServiceResult<IEnumerable<ResultPropertyCollection>> FindAll(DirectoryEntry searchRoot, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties);
|
||||
DataResult<IEnumerable<ResultPropertyCollection>> FindAll(DirectoryEntry searchRoot, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties);
|
||||
|
||||
IServiceResult<IEnumerable<ResultPropertyCollection>> FindAllByUserCache(string username, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties);
|
||||
DataResult<IEnumerable<ResultPropertyCollection>> FindAllByUserCache(string username, string filter, SearchScope searchScope = SearchScope.Subtree, int sizeLimit = 5000, params string[] properties);
|
||||
|
||||
void SetSearchRootCache(string username, string password);
|
||||
|
||||
|
||||
@ -1,185 +0,0 @@
|
||||
namespace DigitalData.Core.Contracts.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the base functionality for a service, including creating service messages and results.
|
||||
/// </summary>
|
||||
public interface IResponseService
|
||||
{
|
||||
#region WITHOUT_MESSAGE
|
||||
|
||||
/// <summary>
|
||||
/// Creates a simple service message indicating success or failure without any additional messages.
|
||||
/// </summary>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <returns>A service message indicating the outcome of the operation without any messages.</returns>
|
||||
IServiceMessage CreateMessage(bool isSuccess);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service result with the specified data and a success flag, without any additional messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result will contain.</typeparam>
|
||||
/// <param name="data">The data for the service result.</param>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <returns>A service result containing the data and indicating the outcome of the operation without any messages.</returns>
|
||||
IServiceResult<T> CreateResult<T>(T? data, bool isSuccess);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service message indicating a successful operation without any messages.
|
||||
/// </summary>
|
||||
/// <returns>A service message indicating a successful operation.</returns>
|
||||
IServiceMessage Successful();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service message indicating a failed operation without any messages.
|
||||
/// </summary>
|
||||
/// <returns>A service message indicating a failed operation.</returns>
|
||||
IServiceMessage Failed();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a successful service result with the specified data, without any messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result will contain.</typeparam>
|
||||
/// <param name="data">The data to include in the service result.</param>
|
||||
/// <returns>A successful service result containing the data, indicating a successful operation without any messages.</returns>
|
||||
IServiceResult<T> Successful<T>(T data);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a failed service result, optionally including data, without any messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result can contain.</typeparam>
|
||||
/// <param name="data">Optional data to include in the failed service result.</param>
|
||||
/// <returns>A failed service result, which may or may not contain data, indicating a failed operation without any messages.</returns>
|
||||
IServiceResult<T> Failed<T>(T? data = default);
|
||||
|
||||
#endregion
|
||||
#region WITH_STRING_MESSAGE
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service message.
|
||||
/// </summary>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <param name="messages">The messages associated with the operation.</param>
|
||||
/// <returns>A service message indicating the outcome of the operation and any associated messages.</returns>
|
||||
IServiceMessage CreateMessage(bool isSuccess, params string[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service result with the specified data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result will contain.</typeparam>
|
||||
/// <param name="data">The data for the service result.</param>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <param name="messages">The messages associated with the operation.</param>
|
||||
/// <returns>A service result containing the data and indicating the outcome of the operation.</returns>
|
||||
IServiceResult<T> CreateResult<T>(T? data, bool isSuccess, params string[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a successful service message.
|
||||
/// </summary>
|
||||
/// <param name="messages">The success messages.</param>
|
||||
/// <returns>A successful service message.</returns>
|
||||
IServiceMessage Successful(params string[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a failed service message.
|
||||
/// </summary>
|
||||
/// <param name="messages">The failure messages.</param>
|
||||
/// <returns>A failed service message.</returns>
|
||||
IServiceMessage Failed(params string[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a successful service result with the specified data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result will contain.</typeparam>
|
||||
/// <param name="data">The data to include in the service result.</param>
|
||||
/// <param name="messages">The success messages.</param>
|
||||
/// <returns>A successful service result containing the data.</returns>
|
||||
IServiceResult<T> Successful<T>(T data, params string[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a failed service result, optionally including data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result can contain.</typeparam>
|
||||
/// <param name="data">Optional data to include in the failed service result.</param>
|
||||
/// <param name="messages">The failure messages.</param>
|
||||
/// <returns>A failed service result, which may or may not contain data.</returns>
|
||||
IServiceResult<T> Failed<T>(T? data = default, params string[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a failed service result without explicitly including data, using only failure messages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This overload is useful when you want to indicate a failure without the need to return any specific data,
|
||||
/// but still want to provide details about the failure through messages.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of data the service result can contain. The result will contain the default value for this type.</typeparam>
|
||||
/// <param name="messages">An array of failure messages associated with the operation. These provide detail about why the operation failed.</param>
|
||||
/// <returns>A failed service result. The data part of the result will be set to the default value for the specified type.</returns>
|
||||
IServiceResult<T> Failed<T>(params string[] messages);
|
||||
|
||||
#endregion
|
||||
#region WITH_ENUM_MESSAGE
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service message using enumeration values.
|
||||
/// </summary>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <param name="messages">The enumeration values associated with the operation.</param>
|
||||
/// <returns>A service message indicating the outcome of the operation and any associated enumeration values.</returns>
|
||||
IServiceMessage CreateMessage(bool isSuccess, params Enum[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a service result with the specified data and enumeration values for messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result will contain.</typeparam>
|
||||
/// <param name="data">The data for the service result.</param>
|
||||
/// <param name="isSuccess">Indicates if the operation was successful.</param>
|
||||
/// <param name="messages">The enumeration values associated with the operation.</param>
|
||||
/// <returns>A service result containing the data and indicating the outcome of the operation with enumeration values.</returns>
|
||||
IServiceResult<T> CreateResult<T>(T? data, bool isSuccess, params Enum[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a successful service message using enumeration values.
|
||||
/// </summary>
|
||||
/// <param name="messages">The success enumeration values.</param>
|
||||
/// <returns>A successful service message.</returns>
|
||||
IServiceMessage Successful(params Enum[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a failed service message using enumeration values.
|
||||
/// </summary>
|
||||
/// <param name="messages">The failure enumeration values.</param>
|
||||
/// <returns>A failed service message.</returns>
|
||||
IServiceMessage Failed(params Enum[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a successful service result with the specified data, using enumeration values for messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result will contain.</typeparam>
|
||||
/// <param name="data">The data to include in the service result.</param>
|
||||
/// <param name="messages">The success enumeration values.</param>
|
||||
/// <returns>A successful service result containing the data.</returns>
|
||||
IServiceResult<T> Successful<T>(T data, params Enum[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a failed service result, optionally including data, using enumeration values for messages.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of data the service result can contain.</typeparam>
|
||||
/// <param name="data">Optional data to include in the failed service result.</param>
|
||||
/// <param name="messages">The failure enumeration values.</param>
|
||||
/// <returns>A failed service result, which may or may not contain data.</returns>
|
||||
IServiceResult<T> Failed<T>(T? data = default, params Enum[] messages);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a failed service result without explicitly including data, using only enumeration values for failure messages.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This overload is useful when you want to indicate a failure without the need to return any specific data,
|
||||
/// but still want to provide details about the failure through enumeration values.
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of data the service result can contain. The result will contain the default value for this type.</typeparam>
|
||||
/// <param name="messages">An array of enumeration values associated with the operation. These provide detail about why the operation failed.</param>
|
||||
/// <returns>A failed service result. The data part of the result will be set to the default value for the specified type.</returns>
|
||||
IServiceResult<T> Failed<T>(params Enum[] messages);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
namespace DigitalData.Core.Contracts.Application
|
||||
{
|
||||
public interface IServiceBase : IResponseService
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DigitalData.Core.Contracts.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a structured format for service messages, categorizing them into success indicators and various types of messages.
|
||||
/// This interface segregates messages into client-facing messages and different levels of logging messages, facilitating targeted communications and diagnostics.
|
||||
/// Properties are initialized once per instance and cannot be modified afterwards, promoting immutability.
|
||||
/// </summary>
|
||||
public interface IServiceMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the service operation was successful.
|
||||
/// </summary>
|
||||
bool IsSuccess { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the list of flags that indicate specific types of statuses or conditions in a service operation.
|
||||
/// These flags help in categorizing the state of the operation more granularly, allowing for multiple conditions to be represented simultaneously.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public ICollection<Enum> Flags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Checks if any of the current service message's flags matches the specified flag based on their string representations.
|
||||
/// This method is useful for conditional logic where the exact string representation of the flag values is crucial.
|
||||
/// </summary>
|
||||
/// <param name="flag">The flag to check against the current service message's flags.</param>
|
||||
/// <returns>true if a flag with a matching string representation exists; otherwise, false.</returns>
|
||||
public bool HasFlag(Enum flag) => Flags.Any(f => f.ToString() == flag.ToString());
|
||||
|
||||
/// <summary>
|
||||
/// [Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
/// Gets a collection of messages associated with the service operation. These messages can be error descriptions,
|
||||
/// success notifications, or other relevant information related to the operation's outcome.
|
||||
/// </summary>
|
||||
[Obsolete("Deprecated: Use ClientMessages instead.")]
|
||||
ICollection<string> Messages { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages intended for client display. This replaces the deprecated 'Messages' property.
|
||||
/// </summary>
|
||||
ICollection<string> ClientMessages { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages used for tracing program execution at a fine-grained level. These are typically voluminous and detailed.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
ICollection<string> TraceMessages { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages helpful for debugging during development. These messages are often diagnostic.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
ICollection<string> DebugMessages { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of informational messages, less critical than warnings, generally used for non-critical notifications.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
ICollection<string> InformationMessages { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages indicating potential issues that are not necessarily errors, but which may require attention.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
ICollection<string> WarningMessages { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of error messages indicating failures or problems within the service.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
ICollection<string> ErrorMessages { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of messages indicating critical issues that require immediate attention.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
ICollection<string> CriticalMessages { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new message to the appropriate collection based on the message type.
|
||||
/// </summary>
|
||||
/// <param name="message">The message to add.</param>
|
||||
/// <returns>The current instance of IServiceMessage, allowing for method chaining.</returns>
|
||||
IServiceMessage WithMessage(string message);
|
||||
|
||||
/// <summary>
|
||||
/// Adds a message corresponding to a specified message key to the appropriate collection, facilitating localization and standardization.
|
||||
/// </summary>
|
||||
/// <param name="messageKey">The enum value representing the message key.</param>
|
||||
/// <returns>The current instance of IServiceMessage, allowing for method chaining.</returns>
|
||||
IServiceMessage WithMessageKey(Enum messageKey);
|
||||
}
|
||||
}
|
||||
@ -1,19 +0,0 @@
|
||||
namespace DigitalData.Core.Contracts.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the outcome of a service operation, extending IServiceMessage with the addition of a data payload.
|
||||
/// This interface is generic, allowing for the specification of the type of data returned by the service operation.
|
||||
/// It is used to communicate not just the success or failure of an operation, but also to return any relevant data
|
||||
/// along with the operation's outcome.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data associated with the service operation's outcome. This could be a model,
|
||||
/// a collection of models, or any other type relevant to the operation.</typeparam>
|
||||
public interface IServiceResult<T> : IServiceMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the data resulting from the service operation. This property is nullable to accommodate operations
|
||||
/// that might not return data upon failure.
|
||||
/// </summary>
|
||||
T? Data { get; set; }
|
||||
}
|
||||
}
|
||||
@ -24,6 +24,10 @@
|
||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DigitalData.Core.DTO\DigitalData.Core.DTO.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="icon.png">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
|
||||
7
DigitalData.Core.Contracts/IFlag.cs
Normal file
7
DigitalData.Core.Contracts/IFlag.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace DigitalData.Core.Contracts
|
||||
{
|
||||
internal interface IError
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
using AutoMapper;
|
||||
|
||||
namespace DigitalData.Core.Application
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
public static class AutoMapperExtension
|
||||
{
|
||||
@ -1,4 +1,4 @@
|
||||
namespace DigitalData.Core.Application.DTO
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents settings related to user cookie consent dialogs. Designed to be serialized into JSON format for use with JavaScript frontend libraries,
|
||||
22
DigitalData.Core.DTO/DIExtensions.cs
Normal file
22
DigitalData.Core.DTO/DIExtensions.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Configuration;
|
||||
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
public static class DIExtensions
|
||||
{
|
||||
public static IServiceCollection AddCookieConsentSettings(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton(sp =>
|
||||
{
|
||||
var configuration = sp.GetRequiredService<IConfiguration>();
|
||||
var settings = configuration.GetSection("CookieConsentSettings").Get<CookieConsentSettings>();
|
||||
return settings is null
|
||||
? throw new ConfigurationErrorsException("The 'CookieConsentSettings' section is missing or improperly configured in appsettings.json.")
|
||||
: settings;
|
||||
});
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
110
DigitalData.Core.DTO/DTOExtensions.cs
Normal file
110
DigitalData.Core.DTO/DTOExtensions.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Text;
|
||||
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
public static class DTOExtensions
|
||||
{
|
||||
public static T Message<T>(this T result, string message) where T : Result
|
||||
{
|
||||
result.Messages.Add(message);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T Message<T>(this T result, params string[] messages) where T : Result
|
||||
{
|
||||
result.Messages.AddRange(messages);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T Notice<T>(this T result, Notice notice) where T : Result
|
||||
{
|
||||
result.Notices.Add(notice);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T Notice<T>(this T result, params Notice[] notices) where T : Result
|
||||
{
|
||||
result.Notices.AddRange(notices);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T Notice<T>(this T result, LogLevel level, params Enum[] flags) where T : Result
|
||||
{
|
||||
var notices = flags.Select(flag => new Notice()
|
||||
{
|
||||
Flag = flag,
|
||||
Level = level
|
||||
});
|
||||
result.Notices.AddRange(notices);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T Notice<T>(this T result, LogLevel level, Enum flag, params string[] messages) where T : Result
|
||||
{
|
||||
result.Notices.Add(new Notice()
|
||||
{
|
||||
Flag = flag,
|
||||
Level = level,
|
||||
Messages = messages.ToList()
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public static T Notice<T>(this T result, LogLevel level, params string[] messages) where T : Result
|
||||
{
|
||||
result.Notices.Add(new Notice()
|
||||
{
|
||||
Flag = null,
|
||||
Level = level,
|
||||
Messages = messages.ToList()
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
public static I Then<I>(this Result result, Func<I> Try, Func<List<string>, List<Notice>, I> Catch)
|
||||
{
|
||||
return result.IsSuccess ? Try() : Catch(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
public static I Then<T, I>(this DataResult<T> result, Func<T, I> Try, Func<List<string>, List<Notice>, I> Catch)
|
||||
{
|
||||
return result.IsSuccess ? Try(result.Data) : Catch(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
public static async Task<I> Then<I>(this Task<Result> tResult, Func<I> Try, Func<List<string>, List<Notice>, I> Catch)
|
||||
{
|
||||
Result result = await tResult;
|
||||
return result.IsSuccess ? Try() : Catch(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
public static async Task<I> Then<T, I>(this Task<DataResult<T>> tResult, Func<T, I> Try, Func<List<string>, List<Notice>, I> Catch)
|
||||
{
|
||||
DataResult<T> result = await tResult;
|
||||
return result.IsSuccess ? Try(result.Data) : Catch(result.Messages, result.Notices);
|
||||
}
|
||||
|
||||
public static void LogNotice<T>(this ILogger<T> logger, IEnumerable<Notice> notices, string start = ": ", string seperator = ". ", string end = ".\n")
|
||||
{
|
||||
foreach(LogLevel level in Enum.GetValues(typeof(LogLevel)))
|
||||
{
|
||||
var logNotices = notices.Where(n => n.Level == level);
|
||||
|
||||
if (!logNotices.Any())
|
||||
continue;
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach(Notice notice in logNotices)
|
||||
{
|
||||
if (notice.Flag is not null)
|
||||
sb.Append(notice.Flag);
|
||||
|
||||
if (notice.Messages.Any())
|
||||
sb.Append(start).Append(string.Join(seperator, notice.Messages)).AppendLine(end);
|
||||
else sb.Append(end);
|
||||
}
|
||||
logger.Log(level, sb.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
DigitalData.Core.DTO/DataResult.cs
Normal file
10
DigitalData.Core.DTO/DataResult.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
public class DataResult<T> : Result
|
||||
{
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public required T Data { get; init; }
|
||||
}
|
||||
}
|
||||
17
DigitalData.Core.DTO/DigitalData.Core.DTO.csproj
Normal file
17
DigitalData.Core.DTO/DigitalData.Core.DTO.csproj
Normal file
@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="13.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,4 +1,4 @@
|
||||
namespace DigitalData.Core.Application
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines flags that indicate specific types of status or conditions in a service operation.
|
||||
11
DigitalData.Core.DTO/Notice.cs
Normal file
11
DigitalData.Core.DTO/Notice.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
public class Notice
|
||||
{
|
||||
public Enum? Flag { get; init; } = null;
|
||||
public LogLevel Level { get; init; } = LogLevel.None;
|
||||
public List<string> Messages { get; init; } = new();
|
||||
}
|
||||
}
|
||||
40
DigitalData.Core.DTO/Result.cs
Normal file
40
DigitalData.Core.DTO/Result.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace DigitalData.Core.DTO
|
||||
{
|
||||
public class Result
|
||||
{
|
||||
public bool IsSuccess { get; set; } = false;
|
||||
|
||||
public List<string> Messages { get; init; } = new();
|
||||
|
||||
[JsonIgnore]
|
||||
public List<Notice> Notices = new();
|
||||
|
||||
public DataResult<T> Data<T>(T data) => new()
|
||||
{
|
||||
IsSuccess = IsSuccess,
|
||||
Messages = Messages,
|
||||
Notices = Notices,
|
||||
Data = data
|
||||
};
|
||||
|
||||
public static Result Success() => new() { IsSuccess = true };
|
||||
|
||||
public static Result Fail() => new() { IsSuccess = false };
|
||||
|
||||
public static DataResult<T> Success<T>(T data) => new()
|
||||
{
|
||||
IsSuccess = true,
|
||||
Data = data
|
||||
};
|
||||
|
||||
#pragma warning disable CS8601 // Possible null reference assignment.
|
||||
public static DataResult<T> Fail<T>() => new()
|
||||
{
|
||||
IsSuccess = false,
|
||||
Data = default
|
||||
};
|
||||
#pragma warning restore CS8601 // Possible null reference assignment.
|
||||
}
|
||||
}
|
||||
@ -78,5 +78,11 @@ namespace DigitalData.Core.Infrastructure
|
||||
var result = await _dbContext.SaveChangesAsync();
|
||||
return result > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously counts all entities in the repository.
|
||||
/// </summary>
|
||||
/// <returns>The total number of entities in the repository.</returns>
|
||||
public virtual async Task<int> CountAsync() => await _dbSet.CountAsync();
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.Core.API", "Dig
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.Core.Tests", "DigitalData.Core.Tests\DigitalData.Core.Tests.csproj", "{B54DEF90-C30C-44EA-9875-76F1B330CBB7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalData.Core.DTO", "DigitalData.Core.DTO\DigitalData.Core.DTO.csproj", "{0B051A5F-BD38-47D1-BAFF-D44BA30D3FB7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -39,6 +41,10 @@ Global
|
||||
{B54DEF90-C30C-44EA-9875-76F1B330CBB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B54DEF90-C30C-44EA-9875-76F1B330CBB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B54DEF90-C30C-44EA-9875-76F1B330CBB7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B051A5F-BD38-47D1-BAFF-D44BA30D3FB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0B051A5F-BD38-47D1-BAFF-D44BA30D3FB7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0B051A5F-BD38-47D1-BAFF-D44BA30D3FB7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B051A5F-BD38-47D1-BAFF-D44BA30D3FB7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user