У меня проблемы с реализацией решения для инкапсуляции некоторой логики CRUD и отображений dto-entity внутри отдельного сервиса, и я действительно могу использовать некоторую помощь.
Итак, допустим, у нас есть следующий интерфейс, который предоставляет конечные точки доступа дляхранилище данных, и у нас есть отдельный клиент для каждой организации
public interface IClient<T> where T : class
{
T Get();
void Set(T entity);
}
И затем у нас есть ClientService, который служит агрегатором для предоставления единой точки доступа всем существующим клиентам
public class A { };
public class B { };
public class ClientService
{
private IDictionary<Type, object> _clientDict;
public ClientService(IClient<A> clientA, IClient<B> clientB)
{
_clientDict = new Dictionary<Type, object>
{
{ typeof(A), clientA },
{ typeof(B), clientB }
};
}
public T Get<T>() where T : class
{
var client = this.GetClient<T>();
return client.Get();
}
public void Set<T>(T entity) where T : class
{
var client = this.GetClient<T>();
client.Set(entity);
}
private IClient<T> GetClient<T>() where T : class
{
if (_clientDict.TryGetValue(typeof(T), out object client))
{
return (IClient<T>)client;
}
throw new ArgumentException();
}
}
Пока все хорошо.
Теперь проблема.Мне нужно преобразовать его для использования объектов DTO для работы с IClient<T>
, в то же время принимая модели без DTO к ClientService
.Псевдокод:
public class A { };
public class A_DTO { };
public class B { };
public class B_DTO { };
public class ClientService
{
private IDictionary<Type, object> _clientDict;
public ClientService(IClient<A_DTO> clientA, IClient<B_DTO> clientB)
{
_clientDict = new Dictionary<Type, object>
{
{ typeof(A), clientA },
{ typeof(B), clientB }
};
}
public void Set<T>(T entity) where T : class
{
var dtoType = GetDTOType(T);
var dtoEntity = _autoMapper.Map(entity, typeof(T), GetDTOType(T));
var client = this.GetClient<T, dtoType>();
client.Set(dtoEntity);
}
private IClient<DTO> GetClient<T, DTO>() where T : class
where DTO: class
{
if (_clientDict.TryGetValue(typeof(T), out object client))
{
return (IClient<DTO>)client;
}
throw new ArgumentException();
}
}
Я понимаю, что, поскольку обобщенные типы разрешаются во время компиляции, мы не можем сделать их зависимыми от переменной, но может быть любой другой способ, которым мы можем получитьклиент для работы, т.е. есть ли способ, как мы можем реализовать IClient<T2> GetClient<T1, T2>
, где T1
равно A
, а T2
равно A_DTO
?Обратите внимание, что конечный пользователь не имеет доступа к объектам DTO и поэтому не может предоставить его как общий тип, и все должно происходить изнутри.
Существует ли какая-либо общая реализация или я просто трачу время и должен заняться созданием конкретных методов для каждой клиентской реализации (например, Get<A>()
, Get<B>
и т. Д.)?