开发者

How to connect Controller to Service layer to Repository layer

开发者 https://www.devze.com 2023-01-21 22:51 出处:网络
Lets say I have the following entities that map to database tables (every matching property name can be considered a PK/FK relationship):

Lets say I have the following entities that map to database tables (every matching property name can be considered a PK/FK relationship):

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 { g开发者_C百科et; set; }
}

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

My architecture is as follows: Controller calls Service layer which calls Repository layer.

I have a View called AddExecutive that collects the following information: FirstName, LastName, PhoneNumber, Salary, and OfficeNumber.

What is the best way to commit this data given my architecture? I am thinking I that I would post up a ViewModel that contains all the information I collected and pass it off to a Service method AddExecutive(AddExecutiveViewModel addExecutiveViewModel), then within the Service method I would create new instances of Person, Employee, Executive, and Contact and attach them to each other (Person object) and pass ALL the data off to a Repository method AddExecutive(Person person). The Repository method would then simply commit the data. Does that sound right? What would be a better solution?


So long as you maintain separation of concerns you good. Controller: Binds data to service / model Service: Enforces Business Logic, hands persistence to Repo Repo: performs ACID transactions and queries.

If your viewmodel is decoupled from any sort of framework concerns (i.e.: a POCO) You should be good since you maintain testability.


When you talk about committing data, you're talking about a unit of work. So start there:

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(// ...
}

Now your services come out of the unit of work (because both the unit of work and the repositories share an ObjectContext in the background; ObjectContext is the EF's "native" unit of work). So we can fill in the // ???:

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() is a thin shell around ObjectContext.SaveChanges(). The unit of work is injected with the same ObjectContext as the repositories. The services are EF-ignorant.

For a working (albeit in an early stage) example, see my open source repository/service project, Halfpipe.

0

精彩评论

暂无评论...
验证码 换一张
取 消