Получить общий класс из коллекции на основе другого типа - PullRequest
0 голосов
/ 13 июня 2018

У меня проблемы с реализацией решения для инкапсуляции некоторой логики 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> и т. Д.)?

1 Ответ

0 голосов
/ 13 июня 2018

На самом деле вам не нужно включать свои DTO в ваш класс обслуживания клиентов.Это определенно станет грязным, когда ваша модель начнет расти.Вместо этого вы можете использовать инструмент, подобный AutoMapper , чтобы преобразовать результат из вашего класса обслуживания в ваш dtos.Это довольно просто.У вас может быть что-то вроде этого:

public class A { };

public class DtoA { };

var source = ServiceClass.Get<A>();
var dto = Mapper.Map<A, ADto>(source);

См. Ссылку для более подробной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...