我正在探索实体框架数据库的使用首先,我试图了解我是否应该将行为注入实体,如果是,那么这样做的最佳技术是什么。我通常在过去做过这个以避免贫血域对象。一些用例是我将规范注入实体(规范模式/定义可组合业务规则)的地方,或者我可能将ninject实现的工厂注入到根实体中,其中实现的绑定由策略/工厂方法决定使用点)例如下面,我将使用IOC注入ISomethingSpec实现。
class Foo
{
void DoSomething()
{
if(somethingSpec.SatisfiedBy(this)
{
}
}
}
请问,我是否应该考虑将行为与实体关联的不同模式?或者如果它是合理的,使用部分类/属性和方法注入是我首先使用EF5和数据库的最佳选择吗?
这是我的第一篇文章,所以我希望它的格式不是太远了。我发布的内容是因为我已经查看过类似的其他问题,但我无法就将行为与域对象/ EF实体关联的最佳实践达成共识。
答案 0 :(得分:3)
我使用specification pattern和Entity Framework来过滤从数据库中检索的数据。我认为您可以使用相同的方法并根据您的需求进行调整。
您可以使用DI容器注入您可能需要的规格和其他物体。第一步是为规范对象定义合同,如下所示:
public interface ISpecification<T> where T : class
{
Expression<Func<T, bool>> GetExpression();
bool IsSatisfiedBy(T entity);
}
通用规范对象可以这样定义:
public class Specification<T> : ISpecification<T> where T : class
{
private Expression<Func<T, bool>> expression;
public Expression<Func<T, bool>> GetExpression()
{
return expression;
}
public Specification(Expression<Func<T, bool>> expression)
{
this.expression = expression;
}
public bool IsSatisfiedBy(T entity)
{
var query = (new[] { entity }).AsQueryable();
return query.Any(this.expression);
}
}
然后您可以像这样更改您的Foo类,这样您就可以使用DI / IoC容器注入依赖项:
public class Foo()
{
public ISpecification<Foo> Specification
{
get;
private set;
}
public Foo(ISpecification<Foo> specification)
{
this.Specification = specification;
}
public void DoSomething()
{
if(Specification.SatisfiedBy(this))
{
//...
}
}
}
创建和使用规范:
// example - create one specification
Expression<Func<Foo, bool>> expression = ....;
ISpecification<Foo> fooSpecification = new Specification<Foo>(expression);
// using the specification with linq
var entities = dbContext.Foos.Where(fooSpecification.GetExpression());
// performing validation
var foo = new Foo{
// ....
};
if(fooSpecification.IsSatisfiedBy(foo))
{
// do something....
}
此处有更多详情:
答案 1 :(得分:1)
回答这个问题,经过Rui的有益评论之后的一些调查,我得出的结论是,我向一个实体注入服务的意图是有缺陷的。因此,我原来的问题的答案是使用域事件来减少耦合,或者使用“双调度”,如下面的链接。我目前正在将nServiceBus视为实现域事件的技术(以及作为nServiceBus本身的介绍)
以下文章帮助我清楚了解服务类型以及如何使用域模型: