Я играю с разработкой, управляемой доменом.Я использую стандартную реализацию репозитория, которая определяется следующим образом: (это реализовано как Repository<T>
)
public interface IRepository<T> where T : class, IEventSource, new()
{
T FindByKey(Guid key);
IEnumerable<T> FindByQuery(Predicate<T> filter);
IEnumerable<T> GetAll();
T CreateObject();
}
Допустим, у меня есть класс Order, который нельзя создать без параметра Customer.Я использую CreateObject, чтобы установить ключ сущности с последовательным генератором Guid.
Какое решение минимизирует время разработки и связывание?
- В настоящее время у меня есть конструктор без параметрови я вызываю некоторый метод Initialize (Customer).
- Я мог бы создать ICustomerRepository, но это означало бы, что для каждой сущности требуется дополнительное время разработки.
- Я также могу изменить CreateObject навозьмите
params object[] args
, но это не типобезопасно во время компиляции. - Я мог бы удалить CreateObject и использовать конструкторы для создания объекта, но это означает, что мне нужно иметь доступ к алгоритму генерации Guid везде, где я создаю экземпляробъект, увеличивающий связь.
- В базовом классе для сущности я мог бы установить ключ в конструкторе, уменьшив связь, но требуя некоторой статической ссылки на алгоритм.
Обновление
Я реализовал стратегию после ответа sll.Новая подпись для хранилища теперь:
public interface IRepository<T> where T : class, IEventSource
{
T FindByKey(Guid key);
IEnumerable<T> FindByQuery(Func<T, bool> predicate);
IEnumerable<T> GetAll();
T CreateObject();
T CreateObject(IConstructorParameters parameters);
}
Без параметров CreateObject
создает экземпляр, пытаясь вызвать конструктор без параметров (используя IL Emit для производительности).
Второй CreateObject
пытается создать метод, вызывающий конструктор, в котором свойства IConstructorParameters
соответствуют конструктору объекта Entity.
Реализация:
private Dictionary<Type, Func<IConstructorParameters, T>> _constructionMethods
= new Dictionary<Type, Func<IConstructorParameters, T>>();
public T CreateObject(IConstructorParameters args)
{
T newObject;
if (args == null)
{
args = ConstructorParameters.Empty;
}
Type paramType = args.GetType();
Func<IConstructorParameters, T> constructor;
if (!_constructionMethods.TryGetValue(paramType, out constructor))
{
//Emit IL to create a Func<IConstructorParameters,T>
constructor = CreateConstructor(paramType);
_constructionMethods.Add(paramType, constructor);
}
newObject = constructor(args);
newObject.Key = _guidCreator.Generate();
return newObject;
}