2

我正在探索实体框架数据库的使用,我试图了解是否应该将行为注入实体,如果是,那么最好的技术是什么。我过去通常这样做是为了避免贫血的域对象。几个用例是我将规范注入实体(规范模式/定义可组合业务规则),或者我可能将 ninject 实现的工厂注入根实体,其中实现的绑定由策略/工厂方法确定使用点)因此,例如在下面,我将使用 IOC 注入 ISomethingSpec 实现。

 class Foo
 {
    void DoSomething()
    { 
        if(somethingSpec.SatisfiedBy(this)
        {
        }
    }
}

请问,我应该考虑将行为与实体关联起来的不同模式吗?或者,如果合理的话,在我首先将 EF5 与数据库一起使用的情况下,使用部分类/属性和方法注入是否是最佳选择?

这是我的第一篇文章,所以我希望它的格式不会离题太远。我在查看其他类似问题时发布,但我无法就将行为与域对象/EF 实体关联的最佳实践达成共识。

4

2 回答 2

4

我使用实体框架的规范模式来过滤从数据库中检索到的数据。我认为您可以使用相同的方法并使其适应您的需求。

您可以使用 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....
}

更多细节在这里:

http://ruijarimba.wordpress.com/2011/06/05/entity-framework-and-t4-generate-specification-objects-for-your-entities/

于 2013-02-17T19:38:24.803 回答
2

关于这个问题,在 Rui 的有用评论之后进行了一些调查后,我得出的结论是,我将服务注入实体的意图是有缺陷的。因此,我最初的问题的答案是使用域事件来显着减少耦合,或者按照下面的链接使用“双重调度”。我目前正在将 nServiceBus 视为实现领域事件的技术(并作为 nServiceBus 本身的介绍)

以下文章帮助我理清了服务类型以及如何与域模型一起使用的思路:

领域事件拯救

于 2013-02-23T15:45:34.413 回答