我正在玩Domain Driven Development。我使用的通用存储库实现定义如下:(这实现为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生成器设置实体的Key。
什么是最小化开发时间和耦合的解决方案?
params object[] args
,但在编译时这不是类型安全的。更新
我按照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;
}
答案 0 :(得分:2)
作为建议的一些观点,我会做如下。
答案 1 :(得分:1)
如果您不想要实现IOrderRepository
- 您可以通过CreateObject()
之类的接口抽象IConstructionParameters
方法参数,然后为每个实体实现具体参数,如OrderConstructionParameters
。
这种方法也称为Parameter Object设计模式,其设计原理 - 更多decoupled系统设计。
public interface IRepository<T>
{
T CreateObject(IConstructionParameters parameters);
}
public sealed class OrderConstructionParameters : IConstructionParameters
{
public Customer Customer
{
get;
private set;
}
}