Некоторый контекст
Я пытаюсь создать контроллер веб-API, способный работать с любой реализацией репозитория.Цель состоит в том, чтобы иметь возможность изменять реализации базы данных без необходимости прикасаться к контроллеру.
Репозитории могут работать с разными типами баз данных, следовательно, имеют разные типы столбцов PK.Например, SQL Server обычно использует int, а MongoDB обычно использует строки.Во время выполнения мой контроллер будет введен с правильной реализацией базы данных с помощью интерфейса репозитория.
Проблема
Внедрение зависимостей работает хорошо, и каждая реализация репо работает сама по себе,Проблема возникает на уровне действий в контроллере.
У каждого репо есть свое определение поля Id.Таким образом, репо является общим.Но я не могу отметить параметр действия как общий.Откуда он взял этот тип?Другой вариант - установить его как dynamic
, но это означает, что мне нужно написать код, чтобы определить тип параметра, который я получил во время выполнения, и вручную проанализировать или преобразовать его перед передачей в репозиторий.
Какой-то код
В некотором смысле я пытаюсь добиться чего-то вроде этого:
// ----------------- Interfaces -----------------
interface IRepository
{
Task<object> FindAsync(object id);
}
interface IRepository<TId> : IRepository where TId : struct
{
Task<SomeData> FindAsync(TId id);
}
// ----------------- Base implementation -----------------
class SqlServerRepository : IRepository<int>
{
public async Task<SomeData> FindAsync(int id) { ... }
// Explicit implementation to allow access only through interface reference
async Task<object> IRepository.FindAsync(object id) => await FindAsync((int)id);
}
class MongoDbRepository : IRepository<string>
{
// Same example as SqlServerRepository but for string ids
}
// ----------------- The famous controller -----------------
public class SomeController : Controller
{
private readonly IRepository db;
public SomeController(IRepository db)
{
this.db = db;
}
public async Task<IAsyncResult> Get(dynamic id) // <<<< Problem starts here
{
return await db.FindAsync(id);
}
}
Мой вопрос
Какмогу ли я указать в параметре универсальный параметр (или dynamic
/ что-нибудь еще?) таким образом, чтобы я мог просто передать его в репозиторий без приведения, анализа или ручного труда?