В настоящее время я столкнулся с проблемой, что я пытаюсь создать DAL для моего .NET-приложения, которое позже будет использовать какую-то базу данных NoSQL.
Базы данных NoSQL, которые я оценил к настоящему времени, иногда различаются по типу, который они используют в качестве первичного ключа. Например, MongoDB использует собственный ObjectID
, в то время как RavenDB использует общий string
. Итак, мой вопрос: как мне создать такой DAL, который может обрабатывать разные типы идентификаторов модели домена.Архитектура DAL, использующая общие модели доменов
Моим первым подходом было создание универсальных моделей доменов. Это выглядело примерно так:
// Domain Model
public class Filter<TId> {
public TId Id { get; set; }
// ...
}
// DAO-interface
public interface IFilterDao<TId> {
bool Persist(Filter<TId>);
// ...
}
// This is where the problems begin
public static class DAOFactory {
public static IFilterDAO<T> GetFilterDAO<T>() {
// Implementation of IFilterDAO<T> can't be instantiated because types must be known at compile time
}
}
Комментарий в методе DAO-Factory уже описывает эту проблему: я не могу определить T
во время выполнения, так как соответствующий код генерируется во время компиляции.
Мой второй и третий подход заключался в определении Id
либо object
, либо dynamic
. RavenDB не мог работать с object
, потому что ему нужна строка. Использование dynamic
Я не мог передать lambdas в RavenDB API (ошибка компилятора «Дерево выражений не может содержать динамическую операцию»). И создание деревьев выражений вместо использования lambdas - действительно последний выход, потому что это более трудоемкий процесс.
Итак, я полностью застрял и надеюсь, что кто-то может мне помочь. Спасибо заранее.
ОБНОВЛЕНИЕ: Я, наконец, получил RavenDB для работы с object
, но это не удовлетворительное решение для использования object
.
Но теперь я должен прямо сказать компилятору, что я хочу, например, MongoDBFactory, не так ли? Я имею в виду, что если я создаю фабрику, я все равно должен предоставить такой тип: «DaoFactory factory = new MongoDBFactory();' И именно это я и хотел включить в конфигурацию. –
Правда; как я уже сказал, использование DI становится очень сложным с общими интерфейсами. Я знаю, что это может быть сделано (я считаю, что Microsoft Unity, например, делает это); Я просто не уверен, что это то, что вы действительно хотите сделать. В конце концов, вы все равно должны знать тип TId в своем клиентском коде, не так ли? По всей вероятности, если вы перемещаетесь между совершенно разными базами данных, то перекомпиляция кода будет наименьшей из ваших проблем. –
Я думаю, вы правы, что мне придется столкнуться с некоторыми проблемами на более высоких уровнях. И если DI действительно так сложно, я думаю, что это не выбор. Я не хотел мигрировать между совершенно разными базами данных, но только между похожими (например, только хранилищами документов). Я проверю решение с помощью DI, и если это не удовлетворительно, я, вероятно, унифицирую тип id на 'object'. Спасибо за вашу помощь. +1 за предоставленный ответ. –