在我的 ASP.NET MVC 4 项目中,我仔细遵循了实现存储库和工作单元的示例中的设计原则。
我对文章中的这句话特别感兴趣,是在展示了通用存储库之后写的:
这个通用存储库将处理典型的 CRUD 需求。当特定实体类型有特殊要求时,例如更复杂的过滤或排序,您可以创建一个派生类,该类具有该类型的其他方法。
由于我的应用程序符合这种特殊情况,因此我尝试这样做。我做了一个 GenericRepository 就像文章中的一样,还有一个 SharedContext 类(SharedContext 正是文章中的 UnitOfWork 类,但这个名字对我来说更有意义)
通用存储库:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace BusinessLogicLayer.Repositories
{
public class GenericRepository<T> where T: class
{
internal DbSet<T> _dbSet;
internal DBConnection _context;
#region constructors
public GenericRepository(SharedContext ctx)
{
_context = ctx.Context;
}
public GenericRepository(DBConnection context)
{
_context = context;
_dbSet = context.Set<T>();
}
#endregion
}
}
SharedContext(工作单元)类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BusinessLogicLayer.Repositories
{
public class SharedContext : IDisposable
{
#region repositories
private GenericRepository<Entities.Customer> _customerRepository;
/// <summary>
/// access the Customer entity
/// </summary>
public GenericRepository<Entities.Customer> CustomerRepository
{
get
{
if (_customerRepository == null)
_customerRepository = new GenericRepository<Entities.Customer>(_context);
return _customerRepository;
}
}
#endregion
#region context management
private Entities.DBConnection _context = new Entities.DBConnection();
internal Entities.DBConnection Context { get { return _context; } }
//other methods - save, delete
#endregion
}
}
现在问题来了:注意我是如何暴露上面的 Context 属性的——我怀疑这实际上是有意的,我觉得我这样做是在打破这种模式。我非常喜欢在相同的上下文中通过存储库控制一切的想法,但是我需要一些通用存储库不提供的其他方法 - 所以我创建了一个单独的 CustomerRepository:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
namespace BusinessLogicLayer.Repositories
{
public class CustomerRepository: GenericRepository<Entities.Customer>
{
public CustomerRepository(SharedContext ctx)
: base(ctx)
{ }
public decimal GetCustomerBonusByFrequency()
{
//
}
}
}
...在我的控制器类中,我这样使用:
private SharedContext ctx = new SharedContext();
public PartialViewResult CustomerBonus()
{
CustomerRepository cRepo = new CustomerRepository(ctx);
var bonus = cRepo.GetCustomerBonusByFrequency();
return PartialView(bonus);
}
所以我的两个问题是:
项目清单
这是文章中提到的添加额外功能的预期方式吗?我指的是 CustomRepository 类,这对我来说感觉像是一种模式的破坏,因为已经有一种方法可以通过 GenericRepository(我不再使用)获取客户,而且我正在公开上下文。
如果这很糟糕,那么我应该如何正确地做到这一点?我只需要为我的客户实体提供额外的方法,但要以尊重模式的方式。
谢谢,
编辑:
我需要在 SharedContext 中公开 Context 属性,因为如果我删除 GenericRepository 中的构造函数(它需要一个 SharedContext)和 CustomerRepository 类中的 :base(ctx) ,我会得到:
BusinessLogicLayer.DBModel.Customer 不包含采用 0 个参数的构造函数