Архитектура .net: Создание IRepository <T>в общем - PullRequest
4 голосов
/ 08 декабря 2008

Я использую универсальный интерфейс репозитория, который позволяет мне добавлять, находить, обновлять и удалять объекты разных типов. Затем я реализовал два конкретных репозитория и могу переключать их без изменения приложения. Все чудесно отключено. Но я наткнулся на препятствие. Код внутри моих методов репозитория просто кажется неправильным, и я не могу понять, как это сделать лучше. Вот фрагмент моего кода:

public class OracleRepository<T> : IRepository<T> where T : new()
{
    public IQueryable<T> GetAll()
    {
        if (typeof(T) == typeof(Object1))
        {
            return (IQueryable<T>)DataAccess.GetAllObject1().AsQueryable();

        }

        if (typeof(T) == typeof(Object2))
        {
            return (IQueryable<T>)DataAccess.GetAllObject2().AsQueryable();
        }

        throw new NotImplementedException();
    }
}

Проблема в том, что мой DataAccess (создает объекты из устройства чтения данных) не является универсальным и имеет специальные методы для каждого типа поддерживаемых им объектов.

Могу ли я переписать вышеприведенное, чтобы я избегал списка if-then-elseif, используя дженерики или иное?

1 Ответ

11 голосов
/ 08 декабря 2008

Одним из распространенных шаблонов является использование словаря от типа к функции соответствующего типа. Например:

private static readonly IDictionary<Type, Func<object>> Fetchers =
    new Dictionary<Type, Func<object>>();
    {
        (typeof(Object1), () => DataAccess.GetAllObject1().AsQueryable()),
        (typeof(Object2), () => DataAccess.GetAllObject2().AsQueryable()),
        // etc
    };

public IQueryable<T> GetAll()
{
    Func<object> func = Fetchers[typeof(T)];
    if (func == null)
    {
        throw new NotImplementedException();
    }
    return (IQueryable<T>) func();
}

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

Вы можете перевести вызов на AsQueryable() на GetAll() в зависимости от того, что GetAllObject1() и т. Д. Вернет.

...