2013-02-15 28 views
58

Từ những gì tôi hiểu, MVC phân tách các định nghĩa lớp (mô hình) từ bản trình bày (xem) thông qua "keo" là bộ điều khiển. Bộ điều khiển nên có một trách nhiệm duy nhất và do đó có thể kiểm tra được. ViewModels được sử dụng để tập hợp dữ liệu từ nhiều thực thể và để "xoa bóp" dữ liệu từ bộ điều khiển cho chế độ xem.Tạo một Lớp dịch vụ cho ứng dụng MVC của tôi?

Có vẻ như logic nghiệp vụ không thực sự có một địa điểm ... vì vậy tôi nghĩ một lớp khác cho các dịch vụ sẽ phù hợp. Tôi chỉ không chắc chắn nơi để đặt lớp này, hoặc làm thế nào để xây dựng các dịch vụ - nó phải là một lớp được gọi là "dịch vụ" có chứa một loạt các chức năng? Tôi là một chút mới với MVC, vì vậy bất kỳ tài liệu đọc, mẫu, hoặc loại người mới nói chung sẽ là tuyệt vời.

Trả lời

97

Tôi thường sử dụng Lớp dịch vụ khi phát triển ứng dụng ASP.NET MVC. Nó tương tự như Service Layer Pattern mà Martin Fowler thảo luận trong các mẫu về Kiến trúc Ứng dụng Doanh nghiệp. Nó đóng gói logic kinh doanh của bạn và làm cho bộ điều khiển khá mỏng. Về cơ bản, các bộ điều khiển sử dụng lớp dịch vụ để lấy các mô hình miền sau đó được chuyển thành các mô hình xem. Tôi cũng sử dụng Unit of Work Design Pattern để xử lý giao dịch và Repository Design Pattern để đóng gói lớp truy cập dữ liệu để kiểm tra đơn vị dễ dàng hơn và có thể dễ dàng hoán đổi ORM. Hình này hiển thị các lớp điển hình mà tôi sử dụng trong một ứng dụng MVC.

MVC Architecture

Lớp dịch vụ được dán nhãn là "Ứng dụng hoặc miền Layer" trong sơ đồ này bởi vì tôi tìm thấy những người bị lẫn lộn khi bạn sử dụng thuật ngữ "Dịch vụ của Layer". Họ có xu hướng nghĩ rằng đây là một dịch vụ web. Nó thực sự là một hội đồng có thể được sử dụng bởi công nghệ dịch vụ web yêu thích của bạn, chẳng hạn như ASP.NET Web API hoặc WCF, cũng như một bộ điều khiển.

Đối với quy ước đặt tên, tôi thường sử dụng nội dung mô tả miền theo sau dịch vụ.Ví dụ, nếu tôi có một lớp dịch vụ xử lý thành viên người dùng thì tôi sẽ có một lớp được gọi là MembershipService có tất cả các phương thức cần thiết bởi bộ điều khiển và dịch vụ web để truy vấn và thao tác miền thành viên. Lưu ý rằng bạn có thể có nhiều miền trong cùng một ứng dụng để bạn có thể có nhiều lớp dịch vụ. Quan điểm của tôi ở đây là bạn không cần phải có một dịch vụ nguyên khối để xử lý toàn bộ ứng dụng.

+0

Cảm ơn Kevin. >>> – user2062383

+4

Có một ví dụ điển hình nào để thực hiện phương pháp này không? – Animesh

+0

@Animesh bạn chỉ cần soạn với các ví dụ trong mạng, mẫu EF + Code First hoặc POCO cho DAL, T4Scaffolding để tạo Kho lưu trữ và UnitOfWork, Dịch vụ chỉ là sự phối hợp giữa DAL và POCO đóng gói logic nghiệp vụ. Sau đó, ASP.NET MVC Controller OR WebApi chỉ gọi lớp dịch vụ và hiển thị kết quả (ASP.NET MVC) hoặc hiển thị nó cho khách hàng khác (ASP.NET WebApi) –

3

Có vẻ như bạn muốn theo dõi một thứ gì đó giống như mẫu kho lưu trữ. Bạn có thể đọc về nó ở đây:

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

Câu trả lời này ở đây cũng có thể giúp:

Best Repository Pattern for ASP.NET MVC

+1

Nó không chỉ là mẫu kho lưu trữ. Các dịch vụ về truy cập dữ liệu _too_, nhưng không phải là độc quyền. – boj

7

Hãy nhìn vào các article từ thực hành tốt nhất MSDN.

Mã nguồn của ứng dụng trong bài viết có thể được tìm thấy here.

21

Lời khuyên của tôi là tạo một lớp riêng biệt gọi là "dịch vụ". Đặt chúng trong dự án thư viện lớp (hoặc không gian tên) khác nhau và làm cho chúng độc lập với cơ sở hạ tầng khung MVC. Tôi khuyên bạn nên sử dụng một số loại tiêm phụ thuộc (tốt nhất là tiêm xây dựng). Sau đó, các lớp dịch vụ của bạn có thể trông giống như:

public class MyService : IMyService 
{ 
    IFirstDependency _firstService; 
    ISecondDependency _secondService; 

    public MyService(IFirstDependency firstService, ISecondDependency secondService) 
    { 
    } 

    public Result DoStuf(InputDTO) 
    { 
     // some important logic   
    } 
} 

Sau đó, bạn sử dụng các dịch vụ này từ bộ điều khiển của mình. Hãy xem here để có ví dụ hoàn chỉnh.

Theo kho lưu trữ - lời khuyên của tôi là không sử dụng chúng nếu bạn sử dụng một số ORM hiện đại (NHibernate, EntityFramework), vì logic nghiệp vụ của bạn sẽ được đóng gói trong Lớp dịch vụ và cơ sở dữ liệu của bạn sẽ được đóng gói với Khung ORM.

+1

Tôi nghĩ rằng vấn đề với bỏ qua phần kho lưu trữ và đi tới ORM là các lớp dịch vụ của bạn sẽ trực tiếp nhận được ngữ cảnh ORM, nghĩa là tất cả các lớp đó trong dịch vụ của bạn sẽ có quyền truy cập vào tất cả các bảng mà bạn đã kéo vào ngữ cảnh thay vì lớp dịch vụ chỉ làm việc với các bảng mà nó cần. Bạn có thể tránh điều này bằng cách đi vào DbSet's vào ctor của mỗi class và giải quyết điều đó với DI nhưng bạn có thể gặp vấn đề với điều đó? – user441521

6

Trích dẫn từ “Business logic should be in a service, not in a model”?:

Trong một MVP/MVC/MVVM/MV * kiến ​​trúc, dịch vụ không tồn tại. Hoặc nếu có, thuật ngữ được sử dụng để chỉ bất kỳ đối tượng chung chung nào có thể được đưa vào bộ điều khiển hoặc mô hình xem. Logic nghiệp vụ nằm trong mô hình của bạn. Nếu bạn muốn tạo "các đối tượng dịch vụ" để dàn xếp các hoạt động phức tạp, thì đó được xem như là một chi tiết thực hiện. Rất nhiều người, thật đáng buồn, thực hiện MVC như thế này, nhưng nó được coi là một mô hình chống (Anemic Domain Model) vì bản thân mô hình không làm gì cả, nó chỉ là một loạt các thuộc tính cho giao diện người dùng.

Một số người nhầm tưởng rằng dùng phương pháp điều khiển 100 dòng và đẩy tất cả vào một dịch vụ bằng cách nào đó làm cho một kiến ​​trúc tốt hơn. Nó thực sự không; tất cả những gì nó làm là thêm một lớp khác, có lẽ là không cần thiết của indirection. Thực tế, bộ điều khiển vẫn đang thực hiện công việc, nó chỉ làm như vậy thông qua một đối tượng "helper" có tên kém. Tôi rất khuyên bạn nên trình bày Wicked Domain Models của Jimmy Bogard cho một ví dụ rõ ràng về cách biến mô hình miền thiếu máu thành mô hình hữu ích. Nó bao gồm việc kiểm tra cẩn thận các mô hình mà bạn đang trưng ra và các hoạt động nào thực sự hợp lệ trong ngữ cảnh kinh doanh.

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