从泛型接口继承的泛型类中令人困惑的字段分配
本文关键字:字段 分配 泛型接口 继承 泛型类 | 更新日期: 2023-09-27 18:29:23
我正在阅读有关存储库模式设计的文章。这篇文章真的很好,但我不理解构造函数中的一些东西。
在此代码中:
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(int id);
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(int id);
}
/// <summary>
/// The EF-dependent, generic repository for data access
/// </summary>
/// <typeparam name="T">Type of entity for this Repository.</typeparam>
public class MyRepository<T> : IRepository<T> where T : class
{
public MyRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("Null DbContext");
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
protected DbContext DbContext { get; set; }
protected DbSet<T> DbSet { get; set; }
public virtual IQueryable<T> GetAll()
{
return DbSet;
}
public virtual T GetById(int id)
{
return DbSet.Find(id);
}
public virtual void Add(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
}
public virtual void Update(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State == EntityState.Detached)
{
DbSet.Attach(entity);
}
dbEntityEntry.State = EntityState.Modified;
}
public virtual void Delete(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Deleted)
{
dbEntityEntry.State = EntityState.Deleted;
}
else
{
DbSet.Attach(entity);
DbSet.Remove(entity);
}
}
public virtual void Delete(int id)
{
var entity = GetById(id);
if (entity == null) return; // not found; assume already deleted.
Delete(entity);
}
}
在它的构造函数中,我读到:
DbContext = dbContext;
DbSet = DbContext.Set<T>();
这可能有意义,但对我来说没有意义,因为DbContext
的类型不是存储对对象引用的变量。我总是继承DbContext
,创建自己的DbContext
,然后创建它的实例/元素。它在这里有什么特殊的意义吗?我想知道为什么作者没有这样写这行:
MyDbContext dbContext = new MyDbContext();
等等。
感谢
进一步查找该类的源代码,您将看到:
protected DbContext DbContext { get; set; }
这是在声明一个类型为DbContext
的属性,也称为DbContext
。当您在ctor中赋值时,您就是在为此属性赋值。
(作用域规则在C#中的工作方式意味着,在构造函数本身中,DbContext
解析为该名称的类属性,而不是类型DbContext
。)
是的,这可能令人困惑。出于这个原因,作者最好给该属性一个与其类型不同的名称,但这种命名实际上相当常见。
至少,ctor应该这样重写:
public MyRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("Null DbContext");
this.DbContext = dbContext;
this.DbSet = this.DbContext.Set<T>();
}