c# - 我应该如何将行为注入(inject)实体

标签 c# .net entity-framework design-patterns dependency-injection

我首先正在探索 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....
}

更多详细信息请参见:

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

关于c# - 我应该如何将行为注入(inject)实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14924924/

相关文章:

c# - 使用canvas todataurl生成c#图像对象

c# - 在字典中的对象上使用锁会产生 KeyNotFoundException

c# - 混合通用方法和扩展方法

c# - Entity Framework Core 2.0 Add-Migration 不创建任何迁移文件

c# - 如何在 C# 中向 XmlDocument() 的 Root 节点添加属性

c# - 通用类 (.CS) 中的应用程序路径

c# - 以强类型方式使用对象的属性名称

c# - 我如何告诉 Resharper 以不同方式设置这些字段属性的格式?

c# - 将 Entity Framework 链接到新的 Sql 数据类型

c# - SQL 服务器 2008 : Ensure that IncludeMetadataConvention has been added to the DbModelBuilder conventions