【问题标题】:How to connect Controller to Service layer to Repository layer如何将控制器连接到服务层到存储库层
【发布时间】:2011-05-01 02:05:46
【问题描述】:

假设我有以下映射到数据库表的实体(每个匹配的属性名称都可以视为 PK/FK 关系):

public class Person
{
  public int PersonID { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

public class Employee
{
  public int EmployeeID { get; set; }
  public int PersonID { get; set; }
  public int Salary { get; set; }
}

public class Executive
{
  public int ExecutiveID { get; set; }
  public int EmployeeID { get; set; }
  public string OfficeNumber { get; set; }
}

public class Contact
{
  public int ContactID { get; set; }
  public int PersonID { get; set; }
  public string PhoneNumber { get; set; }
}

我的架构如下:Controller调用Service层,该层又调用Repository层。

我有一个名为 AddExecutive 的视图,它收集以下信息:FirstName, LastName, PhoneNumber, SalaryOfficeNumber

根据我的架构,提交这些数据的最佳方式是什么?我想我会发布一个包含我收集的所有信息的 ViewModel 并将其传递给服务方法AddExecutive(AddExecutiveViewModel addExecutiveViewModel),然后在服务方法中我将创建Person, Employee, Executive,Contact 的新实例并附加它们彼此(Person 对象)并将所有数据传递给存储库方法AddExecutive(Person person)。然后 Repository 方法将简单地提交数据。听起来对吗?有什么更好的解决方案?

【问题讨论】:

    标签: asp.net-mvc entity-framework asp.net-mvc-2 entity-framework-4 repository


    【解决方案1】:

    只要您保持关注点分离就可以了。 控制器:将数据绑定到服务/模型 服务:执行业务逻辑,将持久性交给 Repo Repo:执行 ACID 事务和查询。

    如果您的视图模型与任何类型的框架问题(即:POCO)分离,那么您应该很好,因为您保持可测试性。

    【讨论】:

    • 就关注点分离而言,我主要关心的是(呵呵),我是否应该为每个实体都有一个服务和存储库。为什么我可以只拥有一个执行服务和存储库?是因为其他实体可以联系在一起吗?
    • 没有。服务具有功能性问题。 (基本上是每个用户案例的方法,松散地说)。服务将信息作为输入,无论您是通过原语还是自定义类执行此操作,都取决于您。如果使用自定义类,请确保它保持消息状态,即:不要制作一个大的 ol 状态包来传递您的参数。
    • 您是否会将我上面描述的 AddExecutiveViewModel 视为“大状态包”?
    • 从概念上讲是,但实际上不是,因为它是一个解耦的专用类。本质上给它一个不同的名字可以解决这个问题。试试 AddExecutive(ExecutiveViewModel executionViewModel) 呵呵。
    • 谢谢。并且您同意 Service 方法是填充真实实体类并将它们传递(附加到 Person 对象)到 Repository 的好地方?
    【解决方案2】:

    当您谈论提交数据时,您是在谈论一个工作单元。所以从这里开始:

    public ActionResult AddExecutive(AddExecutiveViewModel addExecutiveViewModel)
    { 
        // simplified; no error handling
        using (var uow = new UnitOfWork()) // or use constructor injection on the controller...
        {
            // ???
            uow.Commit();
        }
        return RedirectToAction(// ...
    }
    

    现在您的服务来自工作单元(因为工作单元和存储库在后台共享一个 ObjectContextObjectContext 是 EF 的“本机”工作单元)。所以我们可以填写// ???

    public ActionResult AddExecutive(AddExecutiveViewModel model)
    { 
        // simplified; no error handling
        using (var uow = new UnitOfWork()) // or use constructor injection on the controller...
        {
            uow.EmployeeService.AddExecutive(model);
            uow.Commit();
        }
        return RedirectToAction(// ...
    }
    

    uow.Commit()ObjectContext.SaveChanges() 周围的薄壳。工作单元注入与存储库相同的ObjectContext。这些服务是 EF 无知的。

    有关工作(尽管处于早期阶段)示例,请参阅我的开源存储库/服务项目,Halfpipe

    【讨论】:

      猜你喜欢
      • 2013-03-19
      • 2014-03-31
      • 2012-03-09
      • 1970-01-01
      • 2016-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多