存储库之间的依赖关系

时间:2015-03-07 23:02:18

标签: c# entity-framework repository domain-driven-design

我正在使用带有DDD的实体框架。

我有以下实体:人,客户,员工

人是抽象的。 客户和员工继承人。 人员引用了人员地址(列表)。

我应该为每种类型设置存储库还是仅针对每种具体类型? (只是客户和员工)

我可以拥有一个存储库Person然后Customer和Employee存储库在内部依赖它以避免冗余代码吗? (通过构造函数注入使用DI)

2 个答案:

答案 0 :(得分:1)

我只有Customer和Employee的存储库。

如果它们之间存在共享逻辑,则将其封装在抽象基类中并使存储库继承它。

所以你最终会得到这种结构:

public interface ICustomerRepo { }

public interface IEmployeeRepo {  }

public abstract class PersonRepoBase<T> {  }

public class CustomerRepo : PersonRepoBase<Customer>, ICustomerRepo { }

public class EmployeeRepo : PersonRepoBase<Employee>, IEmployeeRepo { }

答案 1 :(得分:1)

这并不意味着提供完整的应用程序结构,但是在设计使用不同存储库和继承等时可能需要的内容时,这是一个很好的基础。

// Model stuff...
public interface IBaseEntity
{
    [Key]
    int Id { get; set; }
}

public abstract class BaseEntity : IBaseEntity
{
    [Key]
    public virtual int Id { get; set; }

    // Add some extra fields for all Models that use BaseEntity
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    [Display(Name = "Last Modified")]
    public virtual DateTime LastModified { get; set; }

    [ConcurrencyCheck]
    [Timestamp]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public virtual byte[] Timestamp { get; set; }
}

public class Person : BaseEntity
{
    // Person Model here...
}

public class Employee : Person
{
    // Extra Employee Model items here
}

public class Customer : Person
{
    // Extra Customer Model items here
}
// End Model stuff

// Repository stuff...
public interface IRepository<T> where T : class
{
    IQueryable<T> GetAll();
    T GetById(int? id);
    T Add(T entity);
    void Update(T entity);
    void Delete(T entity);
    void Delete(int id);
    void Commit(); // To save changes rather than performing a save after each Add/Update/Delete etc.
}

public class EFRepository<T> : IRepository<T> where T : class, IBaseEntity
{
    public virtual IQueryable<T> GetAll()
    {
        return DbSet.AsQueryable<T>();
    }

    public virtual T GetById(int? id)
    {
        var item = DbSet.Find(id);
        return item;
    }

    public virtual T Add(T entity)
    {
        DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
        if (dbEntityEntry.State != EntityState.Detached)
        {
            dbEntityEntry.State = EntityState.Added;
        }
        else
        {
            DbSet.Add(entity);
        }
        // SaveChanges() - removed from each DbSet, so can call on all changes in one transaction.
        // Using Unit Of Work Pattern. Can still use it here though if wished.
        return entity;
    }
    // And so on for each storage method.
}

public interface IEmployeeRepository: IRepository<Employee>
public interface ICustomerRepository: IRepository<Customer>

public class EmployeeRepository : EFRepository<Employee>, IEmployeeRepository
public class CustomerRepository : EFRepository<Customer>, ICustomerRepository
// End Repository stuff

基本上,您可以通过声明接口和类几乎没有任何内容来添加新模型及其存储库。一切都继承了基础功能等。 在添加的模型的特殊情况下,您只需要添加新的方法来获取数据库中的记录 - 例如,FindEmployeeByHairColor(颜色),所有其他EF获取,查找等都是相同的,无论类型如何。

这可以非常深入,使用服务来提供对存储库中核心方法的访问,添加工作单元模式以将多个DbSet组合到一个事务中,依此类推。

但是使用这种类型的布局允许我向每个层注入我希望使用的特定存储库/服务,并将所有逻辑保存在一个类中,该类在使用类似逻辑的所有内容中重复使用。

希望这有帮助。