我的POCO课程应该与存储库进行通信吗?如果是这样的话,该怎么做?

时间:2011-05-29 12:45:39

标签: nhibernate dependency-injection ioc-container

我正在使用nHibernate编写ASP.Net webforms应用程序。目前我没有使用任何IoC框架。

首先 - 我的情景:

  1. 我不想允许两个同名的员工。我想启用Employee类来搜索具有相同名称的其他Employee并发出错误。

  2. 一个部门可能有1000名员工。我需要确切知道每个部门有多少员工。我不想将它们全部加载到内存中,因此我使用计算属性 - EmployeesCount。但是,第一次加载Department对象时会初始化此属性。如果我添加/删除员工,则更改不会反映在该属性中。 (特别是因为我正在使用二级缓存,因此我的对象会持续存在多个会话范围)

  3. 我解决这些问题的想法是让我的域对象保持对相应Repository对象的引用 我认为最好的解决方案是让我的存储库实现接口并使用某种IoC容器/ DI机制。

    所以,在员工中我会:

    if (_empRepository.GetEmployeeByName(newEmployeeName) != null) //...
    

    和部门:

    public int EmployeesCount
      {
        get
          {
             return _departmentRepository.GetCurrentEmployeesCount(this);
          }
      }
    

    我的问题:

    1. 这是令人难以忍受的 - 来自DI

      公共员工(IEmployeeRepository存储库)

    2. 或使用IoC容器?

      public Employee()
        {
           _empRepository = container.Resolve<IEmployeeRepository>();
        }
      
      1. 如何实施所需的解决方案?我知道拦截器/ tuplizer是要走的路,但我无法真正理解整个事情。 this是一个很好的例子吗?另外,我应该在哪个命名空间中定义接口,IoC容器等?

3 个答案:

答案 0 :(得分:4)

POC0到持久性关系通常是单向的:持久层知道POCO,但不是相反。

当你让POCO负责搜索同名的其他员工之类的那一刻,你就会把它变成双向的。我会担心你的设计中模块之间的周期增长。

将这项活动纳入P​​OCO可能听起来不错,因为它有助于避免“贫血领域模型”标签,但我不会这样做。我将这些方法放在持久性接口上,让它们处理它。负责完成用例的服务也更有可能想知道重复的员工姓名;让它做出询问,让POCO离开谈话。

这种方法将使您的测试生活更轻松。你会知道进行测试时模块周期会有多痛苦。你必须将太多的机器拖入测试才能使它发挥作用。

答案 1 :(得分:3)

我也认为Pocos不应该知道持久性。您是否考虑过

等替代方案
class Department
{
    public int Id { get; set; }
    public IList<Employee> ActiveEmployees { get; set; }
}

public DepartmentMap()
{
    ...
    HasMany(d => d.ActiveEmployees)
        .KeyColumn("department_id")
        .Where("stillactiveindepartment = true")      // for example
        .ExtraLazyLoad();  // will issue an Count(*) instead of initializing collection, also other methods like Contains() issue an sql
}

对于具有唯一名称的员工:

1)在service / controler中:在保存新员工之前,发出一个查询,检查是否已存在同名员工。

2)数据库中的唯一约束将在保存时提供异常。

3)会话中的自定义拦截器,它挂接了save / flush事件。如果已经有客户,它可以抛出

答案 2 :(得分:1)

另一个答案主要是针对你提出的问题,我同意那里的建议。

有关访问员工计数的问题,请查看使用NHibernate的投影。我会在您的服务层(用于获取员工数量的任何Web服务操作)中使用计数投影进行查询。

编辑:忘了你正在使用服务/存储库/ POCO。在这种情况下,在存储库中创建一个员工计数查询,并从服务中调用它。