我首先正在探索 Entity Framework 数据库的使用,我试图了解是否应该将行为注入(inject)到实体中,如果是,那么执行此操作的最佳技术是什么。我过去通常这样做是为了避免贫血领域对象。有几个用例是我将规范注入(inject)到实体中(规范模式/定义可组合业务规则),或者我可能将 ninject 实现的工厂注入(inject)到根实体中,其中实现的绑定(bind)由策略/工厂方法确定使用点)因此,例如下面的示例,我将使用 IOC 来注入(inject) ISomethingSpec 实现。
class Foo
{
void DoSomething()
{
if(somethingSpec.SatisfiedBy(this)
{
}
}
}
请问,我是否应该考虑使用不同的模式将行为与实体关联起来?或者,如果合理的话,使用部分类/属性和方法注入(inject)是我首先将 EF5 与数据库结合使用的最佳选择吗?
这是我的第一篇文章,所以我希望它的格式不会太离谱。我发帖是因为我查看了其他类似的问题,但我无法就将行为与域对象/EF 实体关联的最佳实践达成共识。
最佳答案
我使用specification pattern使用 Entity Framework 来过滤从数据库检索的数据。我认为您可以使用相同的方法并根据您的需求进行调整。
您可以使用 DI 容器来注入(inject)您的规范和您可能需要的其他对象。第一步是为规范对象定义契约,如下所示:
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 容器注入(inject)依赖项:
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....
}
更多详细信息请参见:
关于c# - 我应该如何将行为注入(inject)实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14924924/