Похожие чаты

Yes, abstracting the logic to be reusable across multiple entities

based on dynamic properties can be achieved using a combination of generics, reflection, and expressions. The idea would be to create a generic validation service that can validate any entity based on specified unique properties.

Here's a high-level approach:

### 1. Define a Generic Repository Method

First, you'd need a way to find an entity by a given property in your repositories. A generic method could look like:

public async Task<TEntity> FindByPropertyAsync<TEntity, TValue>(Expression<Func<TEntity, bool>> predicate) where TEntity : class;

### 2. Create a Generic Validation Service

This service will use reflection to validate entities based on provided properties.

public interface IUniquePropertyValidationService
{
Task<(bool IsValid, string ErrorMessage)> ValidateUniquePropertyAsync<TEntity, TValue>(
TEntity entity,
Expression<Func<TEntity, TValue>> propertySelector,
TValue value,
int? entityId = null) where TEntity : class, new();
}

public class UniquePropertyValidationService : IUniquePropertyValidationService
{
private readonly IUnitOfWork _unitOfWork;

public UniquePropertyValidationService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}

public async Task<(bool IsValid, string ErrorMessage)> ValidateUniquePropertyAsync<TEntity, TValue>(
TEntity entity,
Expression<Func<TEntity, TValue>> propertySelector,
TValue value,
int? entityId = null) where TEntity : class, new()
{
// Convert the property selector to a predicate.
var parameter = Expression.Parameter(typeof(TEntity), "x");
var body = Expression.Equal(propertySelector.Body, Expression.Constant(value, typeof(TValue)));
var lambda = Expression.Lambda<Func<TEntity, bool>>(body, parameter);

var existingEntity = await _unitOfWork.YourGenericRepository.FindByPropertyAsync(lambda);

if (existingEntity != null)
{
// If we have an entityId, we're in update mode, so we check if the found entity's ID matches the updating entity's ID.
var existingEntityId = (int)typeof(TEntity).GetProperty("Id").GetValue(existingEntity);
if (!entityId.HasValue || existingEntityId != entityId.Value)
{
var propertyName = ((MemberExpression)propertySelector.Body).Member.Name;
return (false, $"{typeof(TEntity).Name} with the same {propertyName} already exists.");
}
}

return (true, string.Empty);
}
}

### 3. Use the Service

For instance, for the currency entity:

var validationOutcome = await _uniquePropertyValidationService.ValidateUniquePropertyAsync<Currency, string>(
currencyToUpdate,
x => x.CurrencyCode,
request.CurrencyCode,
request.CurrencyId);

### Caveats:

- This approach assumes all entities have an Id property of type int. Adjustments might be necessary for different setups.
- Reflection can introduce overhead, so while this generic solution is elegant, there might be performance concerns when dealing with large volumes of data or frequent operations.
- The abstraction assumes uniqueness validation is based on a single property. If there are scenarios where uniqueness is based on combinations of properties, further adjustments would be needed.
- This is a more complex solution than having dedicated validation for each entity. Ensure the complexity aligns with your project's needs.

4 ответов

42 просмотра
Leoul-G Автор вопроса

Hey Guys what Do you think of this generic uniqueness validator, it it a good idea ?

how to insert c# code on the message like this ?

Leoul-G Автор вопроса
Houdaifa Bouamine
screenshot how to insert c# code on the message like this ?

surround the code with 3 backticks and right after(or below) the opening backticks write csharp and on the next lines the code

Похожие вопросы

Обсуждают сегодня

Hey everyone! I won’t focus too much on what this person said (it’s clear they don’t understand the scope of what TF and TELOSX are achieving), but I’ll put it simply for thos...
Ana Ojeda
3
как правильно удалить сддм? прописал в etc/portage.use/plasma-meta -sddm , но при обновлении юзов мне предлагает поставить lightdm (ещё лучше 😡), добавил туда - display-manage...
REDis
25
Всем привет! Имеется функция: function IsValidChar(ch: UTF8Char): Boolean; var i: Integer; ValidChars: AnsiString; begin ValidChars := 'abcdefghijklmnopqrstuvwxyzABCDE...
Евгений
44
i have a small doubt i developed a rest API in put mapping (we use if more than one filed needs to be updated by user ) but concern is i am using dto class in that i am u...
Surya
6
Коллеги, я тут для личных нужд пошел ставить MQTT сервер, пощупал mosquitto, но ужаснулся отсутствию такой банальности, как HTTP API для посмотреть список топиков. А тут что,...
Maksim Lapshin
9
#include <stdio.h> #include <stdlib.h> #include <time.h> void mass_first_generate(int mass[5][7]) {     for (int N = 0; N < 5; N++) {         for (int A = 0; A < 7; A++) {   ...
Чувак
6
Telos is at a pivotal moment. While ambitious projects like zkEVM and SNARKtor have shown promise, the delay in delivering EVM 2.0—a cornerstone of the ecosystem—is a growing ...
Trinidad
8
Ready for some fun AND a chance to win TKO Tokens? Join us for exciting minigames in our Telegram group! 🕒 Don’t miss out—games start on today 25 October 2024, at 8 PM! Ge...
Milkyway | Tokocrypto
255
Всем привет! Решаю 99 OCaml Problems и столкнулся со следующей проблемой (прошу палками не забивать, я OCaml практически не трогал до этого момента): open OUnit2 let create_...
К|/|pи/\/\ 6е3yглbIи
2
Hello!!! Moved nodes to another server, but uptime is not transferred. now both servers are working, last time I did the same, only 2 nodes transferred uptime, can you plea...
Kamil
17
Карта сайта