3

感谢您帮助我理解其中的一些内容:

假设我在 MVC 应用程序中有 2 个控制器 - 1 个控制与销售人员相关的视图模型 1 个控制与销售相关的视图模型

每个都有自己的存储库,它使用实体框架访问数据(代码优先)

两个存储库都设置为处理依赖注入,但也有 0 个参数构造函数,默认使用适当的 EF 数据访问。

销售人员控制器使用 _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 对象(在 salesRepository 内)应该通过 salesPerson 存储库访问,还是直接从 dataContext 对象访问?

感谢您的想法和经验

4

3 回答 3

5

从表中SalesRepository检索数据是没有意义的。SalesPerson该数据访问逻辑应该集中在SalesPeopleRepository. 在我看来,跨存储库复制该方法只会使水变得浑浊。

那么为什么不在销售控制器中同时使用SalesRepository和呢?SalesPeopleRepository我只是实例化一个实例SalesPeopleRepository并使用其中已经定义的方法。

此外,如果您的控制器使用依赖注入,您可以将存储库传递给构造函数:

public SalesController (ISalesRepository salesRepository, ISalesPeopleRepository salesPeopleRepository)
{
   this._salesRepository = salesRepository;
   this._salesPeopleRepository = salesPeopleRepository;
}
于 2012-08-07T01:09:25.907 回答
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();
    }
}
于 2012-08-07T06:39:25.460 回答
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 容器中的每个请求中,而不是直接在控制器中创建,大多数 IoC 容器都支持这一点。不知道您使用哪个 IoC 容器,但我最喜欢的是:Autofac 和 Windsor。

对于项目c,您正在将业务逻辑泄漏到存储库层,相反,业务逻辑应该在控制器或单独的层中。存储库只处理您的数据库的 CRUD 操作。

于 2012-08-07T05:55:07.740 回答