2012-02-17 32 views
6

Trong ứng dụng mvc ASP.net của tôi Tôi đang sử dụng Lớp dịch vụ và Kho lưu trữ để giữ bộ điều khiển của tôi mỏng. Một chi tiết đặc trưng chỉ đọc cái nhìn trông như thế này:MVC - Bộ điều khiển cho lớp dịch vụ Truyền thông

public ActionResult Details(int id) 
{ 
    var project = _projectService.GetById(id); 

    return View(Mapper.Map<Project, ProjectDetails>(project)); 
} 

Dịch vụ Lớp:

public class ProjectService : IProjectService 
{ 
    public Project GetById(int id) 
    { 
     var project = _projectRepository.GetProject(id); 

     // do some stuff 

     return project; 
    } 
} 

public class ProjectRepository : IProjectRepository 
{ 
    public Project GetProject(int id) 
    { 
     return context.Projects.Find(id); 
    } 
} 

Chuyển từ lớp dịch vụ cho các mô hình xem là khá dễ dàng vì automapper, có thể san bằng mọi thứ khá dễ dàng. Di chuyển trực tiếp khác, từ mô hình xem để đi vào lớp dịch vụ của tôi là nơi tôi đấu tranh để đưa ra một giải pháp tốt.

Trong trường hợp như Tạo hành động, cách tiếp cận tốt cho điều này là gì?

[HttpPost] 
public ActionResult Create(CreateProjectViewModel model) 
{ 
    if(!ModelState.IsValid) 
    { 
     return View(model); 
    } 

    // TODO 

    return RedirectToAction("Index"); 
} 

Tôi khá chắc chắn rằng các lớp dịch vụ không nên biết gì về quan điểm mô hình, nhưng tôi cũng không nghĩ rằng AutoMapper hoạt động tốt trong kịch bản này, hoặc, vì nó không giỏi tham gia một mô hình bằng phẳng và biến nó thành một vật thể phức tạp.

Trình điều khiển của tôi trông như thế nào để giao tiếp với lớp dịch vụ? Tôi muốn giữ mã trong bộ điều khiển càng nhẹ càng tốt.

+1

Bạn biết đấy, tôi luôn thấy AutoMapper là cồng kềnh theo cách này, sẽ tốt hơn nếu như Resharper có thể thực hiện cách tạo ánh xạ trên các đối tượng phức tạp một cách tự động. Có thể tạo một trình cắm thêm tốt –

+0

Giới thiệu về việc làm mới với AutoMapper: bạn đã xem http://stackoverflow.com/questions/3145062/using-automapper-to-unflatten-a-dto chưa? – rsenna

+0

@rsenna Tôi sẽ xem xét điều đó, cảm ơn. – Dismissile

Trả lời

5

Bạn có thể xác định một ánh xạ hai chiều và sau đó đi theo con đường khác xung quanh:

[HttpPost] 
public ActionResult Create(CreateProjectViewModel model) 
{ 
    if(!ModelState.IsValid) 
    { 
     return View(model); 
    } 

    Project project = Mapper.Map<CreateProjectViewModel, Project>(model); 
    // pass the project entity to your service layer 
    _projectService.Create(project); 

    return RedirectToAction("Index"); 
} 

hoặc nếu bạn đang cập nhật một thực thể đầu tiên bạn có thể muốn lấy thực thể hiện rằng bạn muốn cập nhật từ các dịch vụ:

[HttpPost] 
public ActionResult Update(CreateProjectViewModel model) 
{ 
    if(!ModelState.IsValid) 
    { 
     return View(model); 
    } 

    Project project = _projectService.GetById(model.Id); 
    Mapper.Map<CreateProjectViewModel, Project>(model, project); 

    // pass the project entity to your service layer 
    _projectService.Update(project); 

    return RedirectToAction("Index"); 
} 
+1

Dường như đôi khi điều này không hoạt động tốt vì AutoMapper không thể dễ dàng chuyển từ mô hình phẳng sang mô hình phức tạp. – Dismissile

+1

@Dismissile, tốt, tất cả sẽ phụ thuộc vào cách bạn xác định ánh xạ của bạn. Đó là sự thật rằng nó dễ dàng hơn để san bằng với AutoMapper nhưng bạn cũng có thể đi theo cách khác tròn và tái tạo lại mô hình tên miền ban đầu từ mô hình xem. –

+0

đúng. Đây có phải là cách tiếp cận bạn thường thực hiện trong các dự án của mình không? – Dismissile

1

cách duy nhất tôi đã thấy điều này được thực hiện cho đến nay là để tự tạo ra một loạt các lớp học chuyển đổi mô hình, ví dụ:

public interface ITransformer<out To, in From> 
    where To : class 
{ 
    To Transform(From instance); 
} 

public class SomeDataToSomeViewModelTransformer : ITransformer<SomeViewModel, SomeDataModel> 
{ 
    public SomeViewModel Transform(SomeDataModel instance) 
    { 
     return new SomeViewModel 
      { 
       InvitationId = instance.Id, 
       Email = instance.EmailAddress, 
       GroupId = instance.Group.Id 
      }; 
    } 
} 

Và một triển khai Biến áp khác để quay lại theo cách khác (ViewModel -> DataModel). Và nhờ Bộ điều khiển biết gọi đúng máy biến áp.

Tôi +1 câu hỏi của bạn vì tôi rất muốn nhìn thấy một cách sạch sẽ tốt đẹp để làm điều này quá, mà không cần phải viết một loạt mã theo cách thủ công cho các mô hình bản đồ.

+0

Tôi nghĩ rằng điều này có thể dễ dàng làm việc. Nó sẽ dễ dàng để kết nối các máy biến áp với khuôn khổ Dependency Injection. – Dismissile

0

Nếu lớp dịch vụ của bạn chỉ dành riêng để hỗ trợ ứng dụng MVC của bạn và không có ứng dụng khách nào khác bạn có thể xem xét sử dụng các đối tượng được truyền qua và từ lớp dịch vụ của bạn như một phần của chế độ xem. Điều này sẽ giảm bớt sự cần thiết phải tự động hóa các cuộc gọi đến khi bạn đang gửi trong các đối tượng thực tế cần thiết từ bộ điều khiển.

Bạn cũng có thể xem xét không có các dịch vụ trả về đối tượng miền, điều này có nghĩa là việc tự động hóa nên được gọi với các phương thức dịch vụ thay vì hành động của bộ điều khiển.

+0

Lớp dịch vụ cũng được sử dụng bởi một ứng dụng WCF, vì vậy nó không thể thực sự hoạt động trên các mô hình khung nhìn. – Dismissile

+0

Đủ công bằng. Cách tiếp cận của tôi không phù hợp với bạn. –

Các vấn đề liên quan