EntityFramework 存储库从接口和抽象类驱动:如何在 ASP.NET MVC 上使用依赖项注入
好吧,让我分解一下我一直在尝试做的事情:
首先,这是我的 abstract
通用存储库:
public abstract class Repository<T, C> where T : class where C : DbContext, new() {
private C _entities = new C();
public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate) {
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public void Add(T entity) {
_entities.Set<T>().Add(entity);
}
public void Delete(T entity) {
_entities.Set<T>().Remove(entity);
}
public void Edit(T entity) {
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public void Save() {
_entities.SaveChanges();
}
}
另外,这是我将用于我的 AccommPropertyWebDetailRepository< 的接口/code> 存储库
class
:
public interface IAccommPropertyWebDetailRepository {
IQueryable<AccommPropertyWebDetail> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyWebDetail GetSingle(int accommPropertyWebDetailId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyWebDetail GetSingleByAccommPropertyId(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All);
}
下面是我的 AccommPropertyWebDetailRepository
类:
public class AccommPropertyWebDetailRepository : Repository<AccommPropertyWebDetail, ReservationHubEntities>, IAccommPropertyWebDetailRepository {
ReservationHubEntities _entities = new ReservationHubEntities();
public IQueryable<AccommPropertyWebDetail> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All) {
IQueryable<AccommPropertyWebDetail> query = _entities.AccommPropertyWebDetails;
switch (approvalstatus) {
case ApprovalStatus.Approved:
query = query.Where(x => (x.AccommProperty.IsApproved == true) && (x.AccommProperty.IsLockedForView == false));
break;
case ApprovalStatus.NotApproved:
query = query.Where(x => (x.AccommProperty.IsApproved == false) || (x.AccommProperty.IsLockedForView == true));
break;
}
return query;
}
public AccommPropertyWebDetail GetSingle(int accommPropertyWebDetailId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyWebDetailID == accommPropertyWebDetailId);
return query;
}
public AccommPropertyWebDetail GetSingleByAccommPropertyId(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).Single(x => x.AccommPropertyID == accommPropertyId);
return query;
}
}
所以到目前为止一切都很好(根据我的说法,但我是不知道我错过了什么)。
我遇到的真正问题是在 ASP.NET MVC Web 应用程序方面。
假设我的控制器类如下启动:
public AccommPropertyController(
IAccommPropertyPictureRepository accommpropertypicturerepo) {
_accommpropertypicturerepo = accommpropertypicturerepo;
}
private readonly IAccommPropertyPictureRepository _accommpropertypicturerepo;
对于依赖项注入,我有以下代码(我使用 Ninject 进行依赖项注入):
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel) {
kernel.Bind<IAccommPropertyPictureRepository>().
To<AccommPropertyPictureRepository>();
}
那么, Repository
抽象类应该在哪里适合这里吗?
因为,我没有直接在控制器内部使用 AccommPropertyPictureRepository
,而只使用 IAccommPropertyPictureRepository
接口,所以我的控制器不知道任何关于 Repository
有什么已知的方法可以处理这个恼人的问题吗?
更新1
所以,现在在@Darin的建议之后,我有以下接口
public interface IRepository<T, C> where T : class where C : DbContext {
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
并且我的抽象类如下:
public abstract class Repository<T, C> : IRepository<T, C> where T : class where C : DbContext, new() {
private C _entities = new C();
public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate) {
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public void Add(T entity) {
_entities.Set<T>().Add(entity);
}
public void Delete(T entity) {
_entities.Set<T>().Remove(entity);
}
public void Edit(T entity) {
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public void Save() {
_entities.SaveChanges();
}
}
无法弄清楚其余部分。
更新2
现在我也想出了一些办法。这是 IAccommPropertyPictureRepository
接口:
public interface IAccommPropertyPictureRepository<T, C> : IRepository<T, C> where T : class where C : DbContext {
IQueryable<AccommPropertyPicture> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All);
IQueryable<AccommPropertyPicture> GetAll(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyPicture GetSingle(int accommPropertyPictureId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyPicture GetSingle(Guid accommPropertyPictureGUID, ApprovalStatus approvalstatus = ApprovalStatus.All);
}
这是 AccommPropertyPictureRepository
类:
public class AccommPropertyPictureRepository : Repository<AccommPropertyPicture, ReservationHubEntities>, IAccommPropertyPictureRepository<AccommPropertyPicture, ReservationHubEntities> {
ReservationHubEntities _entities = new ReservationHubEntities();
public IQueryable<AccommPropertyPicture> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All) {
IQueryable<AccommPropertyPicture> query = _entities.AccommPropertyPictures;
switch (approvalstatus) {
case ApprovalStatus.Approved:
query = query.Where(x => (x.AccommProperty.IsApproved == true) && (x.AccommProperty.IsLockedForView == false));
break;
case ApprovalStatus.NotApproved:
query = query.Where(x => (x.AccommProperty.IsApproved == false) || (x.AccommProperty.IsLockedForView == true));
break;
}
return query;
}
public IQueryable<AccommPropertyPicture> GetAll(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).Where(x => x.AccommPropertyID == accommPropertyId);
return query;
}
public AccommPropertyPicture GetSingle(int accommPropertyPictureId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyPictureID == accommPropertyPictureId);
return query;
}
public AccommPropertyPicture GetSingle(Guid accommPropertyPictureGUID, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyPictureGUID == accommPropertyPictureGUID);
return query;
}
}
我现在已经成功构建了。 Ninject
的东西应该保持不变吗?我想我只需要更改控制器构造函数中的一些代码,对吗?
Ok, let me break down what I have been trying to do :
First of all here is the abstract
generic repository of mine :
public abstract class Repository<T, C> where T : class where C : DbContext, new() {
private C _entities = new C();
public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate) {
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public void Add(T entity) {
_entities.Set<T>().Add(entity);
}
public void Delete(T entity) {
_entities.Set<T>().Remove(entity);
}
public void Edit(T entity) {
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public void Save() {
_entities.SaveChanges();
}
}
Also, here is an interface which I will use for my AccommPropertyWebDetailRepository
repository class
:
public interface IAccommPropertyWebDetailRepository {
IQueryable<AccommPropertyWebDetail> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyWebDetail GetSingle(int accommPropertyWebDetailId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyWebDetail GetSingleByAccommPropertyId(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All);
}
And the below one is my AccommPropertyWebDetailRepository
class :
public class AccommPropertyWebDetailRepository : Repository<AccommPropertyWebDetail, ReservationHubEntities>, IAccommPropertyWebDetailRepository {
ReservationHubEntities _entities = new ReservationHubEntities();
public IQueryable<AccommPropertyWebDetail> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All) {
IQueryable<AccommPropertyWebDetail> query = _entities.AccommPropertyWebDetails;
switch (approvalstatus) {
case ApprovalStatus.Approved:
query = query.Where(x => (x.AccommProperty.IsApproved == true) && (x.AccommProperty.IsLockedForView == false));
break;
case ApprovalStatus.NotApproved:
query = query.Where(x => (x.AccommProperty.IsApproved == false) || (x.AccommProperty.IsLockedForView == true));
break;
}
return query;
}
public AccommPropertyWebDetail GetSingle(int accommPropertyWebDetailId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyWebDetailID == accommPropertyWebDetailId);
return query;
}
public AccommPropertyWebDetail GetSingleByAccommPropertyId(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).Single(x => x.AccommPropertyID == accommPropertyId);
return query;
}
}
So everything has been fine so far (according to me but I am not sure what I am missing).
The real problem I have is on the ASP.NET MVC Web application side.
Let's assume that my controller class starts as follows :
public AccommPropertyController(
IAccommPropertyPictureRepository accommpropertypicturerepo) {
_accommpropertypicturerepo = accommpropertypicturerepo;
}
private readonly IAccommPropertyPictureRepository _accommpropertypicturerepo;
And for dependency injection, I have the following code (I am using Ninject for Dependency Injection) :
/// <summary>
/// Load your modules or register your services here!
/// </summary>
/// <param name="kernel">The kernel.</param>
private static void RegisterServices(IKernel kernel) {
kernel.Bind<IAccommPropertyPictureRepository>().
To<AccommPropertyPictureRepository>();
}
So, where is Repository<T, C>
abstract class supposed to fit in here?
Because, I didn't directly use AccommPropertyPictureRepository
inside my controller and only used IAccommPropertyPictureRepository
interface, my controller doesn't know anything about Repository<T, C>
abstract class.
Any known ways of dealing with this annoying issue?
UPDATE 1
So, now after @Darin's suggestion, I have following interface
public interface IRepository<T, C> where T : class where C : DbContext {
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
And my abstract class is as follows :
public abstract class Repository<T, C> : IRepository<T, C> where T : class where C : DbContext, new() {
private C _entities = new C();
public IQueryable<T> FindBy(Expression<Func<T, bool>> predicate) {
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public void Add(T entity) {
_entities.Set<T>().Add(entity);
}
public void Delete(T entity) {
_entities.Set<T>().Remove(entity);
}
public void Edit(T entity) {
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public void Save() {
_entities.SaveChanges();
}
}
Can't figure the rest of it out.
UPDATE 2
Now I have figured something out as well. Here is IAccommPropertyPictureRepository
interface :
public interface IAccommPropertyPictureRepository<T, C> : IRepository<T, C> where T : class where C : DbContext {
IQueryable<AccommPropertyPicture> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All);
IQueryable<AccommPropertyPicture> GetAll(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyPicture GetSingle(int accommPropertyPictureId, ApprovalStatus approvalstatus = ApprovalStatus.All);
AccommPropertyPicture GetSingle(Guid accommPropertyPictureGUID, ApprovalStatus approvalstatus = ApprovalStatus.All);
}
and here is the AccommPropertyPictureRepository
class :
public class AccommPropertyPictureRepository : Repository<AccommPropertyPicture, ReservationHubEntities>, IAccommPropertyPictureRepository<AccommPropertyPicture, ReservationHubEntities> {
ReservationHubEntities _entities = new ReservationHubEntities();
public IQueryable<AccommPropertyPicture> GetAll(ApprovalStatus approvalstatus = ApprovalStatus.All) {
IQueryable<AccommPropertyPicture> query = _entities.AccommPropertyPictures;
switch (approvalstatus) {
case ApprovalStatus.Approved:
query = query.Where(x => (x.AccommProperty.IsApproved == true) && (x.AccommProperty.IsLockedForView == false));
break;
case ApprovalStatus.NotApproved:
query = query.Where(x => (x.AccommProperty.IsApproved == false) || (x.AccommProperty.IsLockedForView == true));
break;
}
return query;
}
public IQueryable<AccommPropertyPicture> GetAll(int accommPropertyId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).Where(x => x.AccommPropertyID == accommPropertyId);
return query;
}
public AccommPropertyPicture GetSingle(int accommPropertyPictureId, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyPictureID == accommPropertyPictureId);
return query;
}
public AccommPropertyPicture GetSingle(Guid accommPropertyPictureGUID, ApprovalStatus approvalstatus = ApprovalStatus.All) {
var query = GetAll(approvalstatus).First(x => x.AccommPropertyPictureGUID == accommPropertyPictureGUID);
return query;
}
}
I have a successful build now. Should Ninject
stuff stay unchanged? I think I only need to change some of the code from my controller constructor, right?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一种可能性是拥有一个包含所有必要操作的基本
IRepository
接口,并将由Repository
抽象类实现为以及通过IAccommPropertyWebDetailRepository
接口。One possibility would be to have a base
IRepository<T, C>
interface containing all the necessary operations and which will be implemented by theRepository<T, C>
abstract class as well as by theIAccommPropertyWebDetailRepository
interface.