Tạo Lớp dịch vụ cho ứng dụng MVC của tôi?


82

Theo những gì tôi hiểu, MVC tách các định nghĩa lớp (mô hình) khỏi bản trình bày (chế độ xem) thông qua "keo" là bộ điều khiển. Bộ điều khiển phải 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.

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

Câu trả lời:


126

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ư Mẫu lớp dịch vụ mà Martin Fowler thảo luận trong Mẫu kiến ​​trúc ứng dụng doanh nghiệp . Nó đóng gói logic nghiệp vụ của bạn và làm cho các bộ điều khiển khá mỏng. Về cơ bản, bộ điều khiển sử dụng lớp dịch vụ để nhận các mô hình miền sau đó được chuyển đổi thành các mô hình khung nhìn. Tôi cũng sử dụng Mẫu thiết kế đơn vị công việc để xử lý các giao dịch và Mẫu thiết kế kho lưu trữ để đó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 cho thấy các lớp điển hình mà tôi sử dụng trong ứng dụng MVC.

Kiến trúc MVC

Lớp dịch vụ được gắn nhãn là "Lớp ứng dụng hoặc lớp miền" trong sơ đồ này vì tôi thấy mọi người bị nhầm lẫn khi bạn sử dụng thuật ngữ "Lớp dịch vụ". Họ có xu hướng nghĩ rằng đây là một dịch vụ web. Nó thực sự là một lắp ráp 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 một cái gì đó mô tả miền theo sau là dịch vụ. Ví dụ: Nếu tôi có một lớp dịch vụ xử lý tư cách thành viên của người dùng thì tôi sẽ có một lớp gọi là MemberhipService có tất cả các phương thức mà bộ điều khiển và dịch vụ web cần để truy vấn và thao tác miền thành viên. Lưu ý rằng bạn có thể có một số miền trong cùng một ứng dụng nên 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 nhất thiết phải có một dịch vụ đơn lẻ đảm nhiệm toàn bộ ứng dụng.


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

@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 HOẶC 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 ứng dụng khách khác (ASP.NET WebApi)
riadh gomri

2
Kho lưu trữ và UoW là không cần thiết, phải không? Ít nhất là trong ví dụ của bạn, khi bạn phải sử dụng chỉ một công nghệ cơ sở dữ liệu (và nó không phải là DDD). Đây là lý do tại sao EF đã tự triển khai UoW và các mẫu kho lưu trữ.
krypru

1
Tôi không biết ở đây, vì tôi thích ví dụ và hình ảnh, nhưng rất nhiều hướng dẫn trực tuyến sử dụng Mẫu kho lưu trữ một cách không cần thiết. Chúng trừu tượng hóa vì chúng có thể trừu tượng hóa mà không mang lại lợi ích gì, chỉ để chúng có thể sử dụng Giao diện.
johnny

Tuyệt vời !!! Cảm ơn bạn @kevin Junghans, Câu trả lời của bạn thực sự đã giúp tôi kiến ​​trúc ứng dụng web phức tạp. Một câu hỏi ngắn, Trong khi phát triển các ứng dụng web dựa trên các dịch vụ vi mô, chúng ta có cần triển khai các lớp Dịch vụ hay chỉ đơn giản là các lớp MVC thực hiện công việc.
codemilan

28

Lời khuyên của tôi là tạo một lớp riêng biệt được 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 trên cơ sở hạ tầng khung MVC. Tôi cũng 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 hàm tạo). 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. Nhìn vào đây để có ví dụ đầy đủ.

Theo Repositories - lời khuyên của tôi là không sử dụng chúng nếu bạn định sử dụng một số ORM hiện đại (NHibernate, EntityFramework), bởi 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.


4
Tôi nghĩ rằng vấn đề với việc bỏ qua phần kho lưu trữ và đi thẳng đến 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, có 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 bạn đã kéo vào ngữ cảnh thay vì từng dịch vụ lớp làm việc chỉ với các bảng mà nó cần. Bạn có thể tránh điều này bằng cách chuyển DbSet's vào ctor của mỗi lớp và giải quyết điều đó bằng DI nhưng bạn có thể gặp sự cố với điều đó?
user441521


10

Trích dẫn từ "Logic kinh doanh nên nằm trong một dịch vụ, không phải trong một mô hình"? :

Trong kiến ​​trúc MVP / MVC / MVVM / MV *, các dịch vụ hoàn toàn không tồn tại. Hoặc nếu có, thuật ngữ này được sử dụng để chỉ bất kỳ đối tượng chung nào có thể được đưa vào bộ điều khiển hoặc mô hình chế độ xem. Logic kinh doanh nằm trong mô hình của bạn. Nếu bạn muốn tạo "đối tượng dịch vụ" để sắp xếp các hoạt động phức tạp, đó được xem như là một chi tiết triển khai. 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 lại mô hình (Mô hình miền thiếu máu) 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 lầm tưởng rằng sử dụng phương pháp bộ điều khiển 100 dòng và chuyển tất cả vào một dịch vụ bằng cách nào đó tạo ra 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 hướng dẫn khác, có thể là không cần thiết. Thực tế mà nói, 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 "người trợ giúp" có tên kém. Tôi thực sự giới thiệu bài thuyết trình Mô hình miền xấu xa của Jimmy Bogard để có ví dụ rõ ràng về cách biến mô hình miền thiếu máu thành một mô hình hữu ích. Nó liên quan đến việc kiểm tra cẩn thận các mô hình bạn đang sử dụng và hoạt động nào thực sự hợp lệ trong bối cảnh kinh doanh.


Đây là câu trả lời tốt nhất. Phương thức được chọn cho biết đặt logic nghiệp vụ trên các dịch vụ sẽ được sử dụng trong bộ điều khiển, nhưng logic nghiệp vụ phải nằm trên mô hình.
Mateus Felipe

3

Có vẻ như bạn đang theo đuổi một cái gì đó giống như một mô hình kho lưu trữ. Bạn có thể đọc nó ở đây:

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implecting-the-repository-and-unit-of-work-patterns-in-an-asp-net- mvc-ứng dụng

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

Mẫu kho lưu trữ tốt nhất cho ASP.NET MVC


4
Nó không chỉ là mô hình kho lưu trữ. Dịch vụ là về truy cập dữ liệu quá , nhưng không phải độc quyền IMHO.
boj
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.