存储库之间的依赖关系
Dependency between repositories
我正在使用 Entity Framework 和 DDD。
我有以下实体:人员、客户、员工
人是抽象的。
客户和员工继承人。
人员引用了人员地址(列表)。
我应该为每种类型都有一个存储库,还是只为每个具体类型都有一个存储库? (仅客户和员工)
我可以有一个存储库 Person 然后客户和员工存储库在内部依赖它以避免冗余代码吗? (通过构造函数注入使用 DI)
我只需要客户和员工的存储库。
如果它们之间存在共享逻辑,则将其封装在抽象基础中 class 并让存储库从中继承。
所以你最终会得到这种结构:
public interface ICustomerRepo { }
public interface IEmployeeRepo { }
public abstract class PersonRepoBase<T> { }
public class CustomerRepo : PersonRepoBase<Customer>, ICustomerRepo { }
public class EmployeeRepo : PersonRepoBase<Employee>, IEmployeeRepo { }
这并不是为了提供完整的应用程序结构,而是为设计您在使用不同的存储库和继承等时可能需要的内容提供良好的基础。
// 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
基本上,您可以通过声明接口和 classes 来添加新模型及其存储库,其中几乎没有任何内容。一切都继承自基本的 crud 功能等。
对于正在添加的模型,您只需要在特殊情况下添加从数据库获取记录的新方法 - 例如 FindEmployeeByHairColor(color),所有其他 EF Gets、Finds 等都是相同的,无论类型如何。
这可以变得非常深入,使用服务提供对存储库中核心方法的访问,添加工作单元模式以将多个 DbSet 组合成一个事务,等等。
但是使用这种类型的布局允许我将我希望使用的特定 Repository/Service 注入到每一层中,并将所有逻辑保存在一个 class 中,并在所有内容中重复使用使用类似的逻辑。
希望对您有所帮助。
我正在使用 Entity Framework 和 DDD。
我有以下实体:人员、客户、员工
人是抽象的。 客户和员工继承人。 人员引用了人员地址(列表)。
我应该为每种类型都有一个存储库,还是只为每个具体类型都有一个存储库? (仅客户和员工)
我可以有一个存储库 Person 然后客户和员工存储库在内部依赖它以避免冗余代码吗? (通过构造函数注入使用 DI)
我只需要客户和员工的存储库。
如果它们之间存在共享逻辑,则将其封装在抽象基础中 class 并让存储库从中继承。
所以你最终会得到这种结构:
public interface ICustomerRepo { }
public interface IEmployeeRepo { }
public abstract class PersonRepoBase<T> { }
public class CustomerRepo : PersonRepoBase<Customer>, ICustomerRepo { }
public class EmployeeRepo : PersonRepoBase<Employee>, IEmployeeRepo { }
这并不是为了提供完整的应用程序结构,而是为设计您在使用不同的存储库和继承等时可能需要的内容提供良好的基础。
// 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
基本上,您可以通过声明接口和 classes 来添加新模型及其存储库,其中几乎没有任何内容。一切都继承自基本的 crud 功能等。 对于正在添加的模型,您只需要在特殊情况下添加从数据库获取记录的新方法 - 例如 FindEmployeeByHairColor(color),所有其他 EF Gets、Finds 等都是相同的,无论类型如何。
这可以变得非常深入,使用服务提供对存储库中核心方法的访问,添加工作单元模式以将多个 DbSet 组合成一个事务,等等。
但是使用这种类型的布局允许我将我希望使用的特定 Repository/Service 注入到每一层中,并将所有逻辑保存在一个 class 中,并在所有内容中重复使用使用类似的逻辑。
希望对您有所帮助。