感谢您帮助我理解其中的一些内容:
假设我在MVC应用程序中有2个控制器 - 1控制与销售人员相关的viewModels 1控制与销售相关的viewModels
每个都有自己的存储库,使用Entity框架(代码优先)访问数据
这两个存储库都设置为处理依赖注入,但也有0个参数构造函数,默认值使用相应的EF dataAccess。
salespeople控制器使用_salesPeopleRepository.getAllSalesPeople()函数返回一个销售人员列表来填充索引视图。
销售控制器需要访问相同的列表来填充下拉列表。
有几种方法可以将信息提供给销售控制人员,我想知道哪些选项被认为是最佳做法:
a)在控制器中
db = new DataContext();
_saleRepos = new SalesRepository(db);
_salesPeople = new SalesPeopleRepository(db);
.....
modelA.SalePeopleSelectList = SelectList(_salesPeople.getAllSalesPeople(),"id","name")
b)在SalesRepository中 - 使用EF本身:
public IEnumerable<salesPerson> getAllSalesPeople()
{
return _db.SalesPeople.ToList();
}
c)或在调用函数
之前实例化并注入相同的数据访问对象public IEnumerable<salesPerson> getAllSalesPeople()
{
return (new SalesPersonRepository(_db)).getAllSalesPeople();
}
修改
如果答案是a),应如何从1个存储库调用自定义商务逻辑 - 例如,sales有一个storeId,并且存储库检查为销售输入的storeId是否与salesPerson的storeId匹配。是否应该通过salesPerson存储库或直接从dataContext对象访问用于商业逻辑目的的salesPerson对象(在salesRepository中)?
感谢您的想法和经验
答案 0 :(得分:5)
从SalesRepository
表中检索SalesPerson
数据是没有意义的。数据访问逻辑应该集中在SalesPeopleRepository
中。在我看来,在存储库中复制方法只会使水变得混乱。
那么为什么不在销售控制器中同时使用SalesRepository
和SalesPeopleRepository
?我只是实例化SalesPeopleRepository
的一个实例,并使用那里已经定义的方法。
此外,如果您的控制器使用依赖注入,您可以将存储库传递给构造函数:
public SalesController (ISalesRepository salesRepository, ISalesPeopleRepository salesPeopleRepository)
{
this._salesRepository = salesRepository;
this._salesPeopleRepository = salesPeopleRepository;
}
答案 1 :(得分:2)
最佳实践总是取决于具体情况,但在EF之上经常使用存储库和工作单元模式的组合
<强>用法:强>
using (var uow as new DataContext()) {
var salesPeople = new SalesPeopleRepository(uow);
// ...
uow.Commit(); // If changes must be committed back to the database
}
<强>实施强>
public interface IUnitOfWork {
public void Commit();
}
public class DataContext : IUnitOfWork {
public void Commit() {
this.SaveChanges();
}
}
public class SalesPeopleRepository {
private DataContext _db
public SalesPeopleRepository(IUnitOfWork uow) {
_db = uow as DataContext;
}
public IEnumerable<SalesPerson> GetAllSalesPeople() {
return _db.SalesPeople.ToList();
}
}
答案 2 :(得分:1)
首先,应该遵循C#命名约定:getAllSalesPeople()应该是GetAllSalesPeople。其次,在这种情况下,IoC容器和依赖注入将是最佳实践。
应该避免使用 a 项,因为DataContext和Repositories直接在控制器中创建,它违反了依赖注入并使您的代码与Repositories和DataContext紧密耦合,无法模拟单元测试。相反,应将存储库注入控制器,并将DataContext注入存储库。
public Repository(DataContext dataContext)
{
_dataContext = dataContext;
}
public SalesController(ISalesRepository salesRepository,
ISalesPeopleRepository salesPeopleRepository)
{
_salesRepository = salesRepository;
_salesPeopleRepository = salesPeopleRepository;
}
DataContext的生命周期管理应保存在IoC Container中的每个请求中,而不是直接在控制器中创建,大多数IoC Container都支持此操作。不知道你使用的是哪个IoC容器,但我最喜欢的是:Autofac和Windsor。
对于项目 c ,您将业务逻辑泄漏到存储库层,而业务逻辑应位于控制器或单独的层中。存储库只处理您的数据库的CRUD操作。