Я ищу способ объединить х количество очень похожих функций CRUD в одну без необходимости использовать х количество операторов if else для проверки типа универсального.
У меня есть контроллеры Web API, с которых я хочу делать вызовы, например:
Service.Get<FooModel>(number, type, part, version);
Это сделано для того, чтобы исключить необходимость иметь чрезвычайно похожую функцию для 40+ конечных точек API.Проблема заключается в том, что когда я получаю это в своем сервисе, я должен проверить тип предоставленного общего и сравнить с этими более 40 типами объектов в одной функции.Все модели в настоящее время наследуются от базовой унаследованной модели.
Текущая общая функция
(функции создания, обновления, удаления аналогичны):
public T Get<T>(string documentNr, string type, string part, string version) where T : InheritedModel, new()
{
try
{
T model = new T();
if (typeof(T) == typeof(InheritedModel))
{
using (var repo = new InheritedModelConsumer(ref _helper))
{
model = (T)repo.Get(documentNr, type, part, version);
}
}
else if (typeof(T) == typeof(FooModel))
{
using (var repo = new FooModelConsumer(ref _helper))
{
model = (T)(object)repo.Get(documentNr, type, part, version);
}
}
else if (typeof(T) == typeof(ComponentModel))
{
using (var repo = new ComponentModelConsumer(ref _helper))
{
model = (T)(object)repo.Get(documentNr, type, part, version);
}
}
else if (typeof(T) == typeof(BarModel))
{
using (var repo = new BarModelConsumer(ref _helper))
{
model = (T)(object)repo.Get(documentNr, type, part, version);
}
}
... and so on
... and so on
...
else
throw new Exception("Type T structure not defined");
return model;
}
catch (Exception)
{
throw;
}
finally
{
_helper.Dispose();
}
}
Это работает, но если это возможно, я ищу что-то, что я могу сказать во время выполнения: "оУ меня есть этот объект типа T, и, поскольку я знаю, что все функции имеют одинаковые входные данные, я собираюсь создать экземпляр этого потребителя типа TConsumer, вызвать consumer.Get (входные данные), а затем вернуть объект T любому APIконтроллер вызвал меня. "
Редактировать
Пример использования простого класса-потребителя
internal sealed class FooConsumer : RepositoryConsumer<Foo, FooRepository, FooFilter>
{
public FooConsumer(ref SqlHelper helper) : base(ref helper) { }
public List<Foo> GetAll(string token)
{
return _repo.Get().Where(x => Extensions.StringContainsToken(x.AccountName, token)).ToList();
}
}
Репозиторий Потребитель, от которого наследуются все потребители.T - модель, K - репозиторий (пользовательский класс ORM), а O - фильтр для предложения WHERE, которое выполняет ORM.
public abstract class RepositoryConsumer<T, K, O> : IDisposable, IRepositoryConsumer<T> where T : class, new() where K : Repository<T, O>, new() where O : QueryFilter, new()
{
/// <summary>
/// Repository instance
/// </summary>
protected K _repo;
/// <summary>
/// Only constructor avaialble. MUst pass SqlHelper instance for transaction support
/// </summary>
/// <param name="sql"></param>
public RepositoryConsumer(ref SqlHelper sql)
{
_repo = Activator.CreateInstance(typeof(K), new object[] { sql }) as K;
}
/// <summary>
/// Allow consumer initializations in using statements
/// </summary>
public void Dispose()
{
}
/// <summary>
/// Create instance of T
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public virtual int Create(T data)
{
return _repo.Create(data);
}
/// <summary>
/// Bulk create instances of T
/// </summary>
/// <param name="contract"></param>
/// <returns></returns>
public virtual int Create(BaseBulkable<T> contract)
{
return _repo.BulkCreate(contract);
}
/// <summary>
/// Get an instance of T based on a single PK field id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual T Get(long id)
{
return _repo.Get(id);
}
/// <summary>
/// Gets all instances of T
/// </summary>
/// <returns></returns>
public virtual List<T> GetAll()
{
return _repo.Get();
}
/// <summary>
/// Updates an instance of T
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public virtual int Update(T data)
{
return _repo.Update(data);
}
/// <summary>
/// Updates an instance of T based on a single PK field id
/// </summary>
/// <param name="id"></param>
/// <param name="data"></param>
/// <returns></returns>
public virtual int Update(long id, T data)
{
return _repo.Update(id, data);
}
/// <summary>
/// Deletes an instance of T
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public virtual int Delete(T data)
{
return _repo.Delete(data);
}
/// <summary>
/// Deletes an instance of T based on a single PK field id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public virtual int Delete(long id)
{
return _repo.Delete(id);
}
}