2015-02-03 14 views
15

Gần đây tôi đã nghe rất nhiều về DTO và chúng hữu ích như thế nào nhưng tôi không thể tìm thấy một ví dụ hay về việc sử dụng nó trong ngữ cảnh ASP.NET.Lớp nào của ứng dụng nên chứa triển khai DTO

Hãy nói rằng tôi sử dụng ba kiến ​​trúc tầng:

  1. lớp dữ liệu (sử dụng Entity Framework)
  2. lớp kinh doanh (WCF Service)
  3. Presentation Layer (MVC ứng 4,0 web)

Tôi nên chuyển từ đối tượng Employee EF sang EmployeeDTO POCO ở đâu?

Cho phép nói rằng tôi thực hiện chuyển đổi trong lớp Truy cập dữ liệu nhưng điều gì xảy ra trong dịch vụ WCF? Sau đó nó có nên được chuyển đổi sang một đối tượng DataMember khác và khi nó đến lớp giao diện người dùng (ứng dụng web MVC) sau đó nó sẽ được chuyển đổi lần thứ ba thành một mô hình không? Tôi sẽ đánh giá cao nếu một người nào đó có thể làm rõ điều này cho tôi

+2

Tôi hiện đang nghiên cứu cho các ứng dụng web mới, stumbled khi bài viết này tốt http://www.codeproject.com/Articles/493389/Four-ways-of-passing-data-between-layers, chỉ muốn chia sẻ – kite

Trả lời

6

Trong tình huống tương tự, tôi đã sử dụng để đặt dto's thành Core được biết đến cả ba. Vì vậy, bạn có

 
    Core 
     | 
------------ 
|  | | 
DAL BL PL 

Mỗi lớp có thể hoạt động với Core.Dto.Employee. Mỗi lớp cũng hiển thị Core.Dto.Employee bên ngoài trong API của nó. Nhưng bên trong mỗi lớp có thể chuyển đổi/điều chỉnh Core.Dto.Employee, ví dụ: bạn đọc từ cơ sở dữ liệu EF.Employee và sau đó chuyển đổi nó thành Core.Dto.Employee. Sự biến đổi được chứa bởi ranh giới của lớp.

Nếu bạn có nhiều mô hình khác nhau để đại diện cho cùng một thứ trong các lớp, ví dụ PL muốn PL.Employee và DAL hoạt động trên EF.Employee, bạn sẽ kết thúc với một mớ hỗn độn.

+2

Điều đó có vẻ tốt hơn và bạn chuyển đổi từ đối tượng EF sang DTO ở đâu? –

+0

Một chút muộn với câu trả lời. Tôi thường cố gắng chứa chuyển đổi bên trong một dự án duy nhất. Thông thường, chuyển đổi chỉ liên quan đến dự án cụ thể đó, ví dụ: đối tượng EF cho DTO có thể sẽ ở trong DAL. Trong một số trường hợp, tôi sử dụng lại nó trong một số dự án - trong trường hợp này tôi chuyển mã thành lõi để tôi có thể sử dụng lại nó và không trùng lặp – oleksii

2

Hãy xem tại đây https://stackoverflow.com/a/6310507/1771365 vì tôi không có đủ danh tiếng để thêm nhận xét.

Cá nhân tôi sẽ chuyển các thực thể giữa lớp Persistence và lớp doanh nghiệp của bạn. Khi bạn đang sử dụng cơ hội MVC là bạn sẽ vượt qua các mô hình xem cho bộ điều khiển của bạn. Tại thời điểm đó tôi sẽ ánh xạ mô hình khung nhìn của bạn tới (các) DTO của bạn.

Nếu bạn dự định sử dụng DTO giữa tất cả các lớp của bạn, sau đó tạo một dự án cắt chéo mà bạn có thể tham khảo.

1

Cách tiếp cận mà tôi đặc biệt thích là chuyển đổi DTO trong Lớp doanh nghiệp của bạn.

Kịch bản: Lớp trình bày của bạn gọi lớp doanh nghiệp của bạn qua DTO. Bạn thực hiện một số xác thực hợp lệ &, sau đó chuyển đổi DTO thành một thực thể và gửi nó đến Lớp Truy cập dữ liệu của bạn.

tức là Giao diện người dùng -> Xe buýt. Lớp (chuyển đổi thành Thực thể) -> Lớp dữ liệu

Tôi thích phương pháp này vì tôi tin rằng Lớp dữ liệu không nên có bất kỳ logic chuyển đổi nào và sẽ nhận và xử lý các thực thể khi cần. Một lý do khác tại sao điều này có hiệu quả là bây giờ bạn có thể xác định các quy tắc nghiệp vụ/logic xác thực cụ thể trong quá trình chuyển đổi trước khi gửi nó đến Lớp dữ liệu. Đây là một số MSDN article cũ, nhưng có một số chi tiết tuyệt vời giải thích cách tiếp cận tương tự.

+0

Và sử dụng cách tiếp cận của bạn, nơi DTO được tạo ra? Trong lớp giao diện người dùng? –

+0

Bạn có thể tiếp cận tạo theo 2 cách, hoặc là bạn đưa ra một phương thức trong Lớp nghiệp vụ của bạn để tạo DTO: 'UserDTO CreateUserDTO()' trả về một DTO mới được khởi tạo. Cách khác (mà tôi thích) là đơn giản khởi tạo nó trong lớp UI: 'var dto = new UserDTO()'. Vì DTO của bạn có sẵn cho giao diện người dùng, bạn có thể đơn giản khởi tạo DTO, điền vào trong giao diện người dùng và sau đó gửi nó ra khỏi lớp kinh doanh để lưu hoặc bất kỳ điều gì khác. Và cuối cùng khi bạn điền DTO từ db của bạn, lớp nghiệp vụ của bạn sẽ đơn giản trả về một cá thể DTO đầy: 'UserDTO GetUserByID (int id)' –

-1

Không được có bất kỳ chuyển đổi nào. Bạn sẽ chỉ sử dụng Poco Objects làm DTO.

EF làm việc với Poco và chúng có thể được WCF tuần tự hóa.

Chúng phải được xác định trong một hội đồng được tất cả các dự án giới thiệu.

Trong ASP.NET MVC bạn sẽ MAPP đến một ViewModel bằng Poco - DTO.

+0

Thật không may đây là một cách tiếp cận dễ vỡ vì bạn không thể thay đổi các đối tượng của mình cho phù hợp với nhu cầu nội bộ của ứng dụng của bạn bởi vì người tiêu dùng bên ngoài dịch vụ của bạn phụ thuộc vào cấu trúc hiện tại của họ. Bằng cách có các DTO riêng biệt được hiển thị qua WCF/Web APIs, bạn cho phép mô hình nội bộ của mình phát triển trong khi vẫn đảm bảo các hợp đồng bên ngoài được giữ lại. – ssmith

5

Lớp dịch vụ của bạn hiển thị DTO. Điều này có nghĩa là trong lớp dịch vụ bạn xác định hợp đồng dữ liệu như bạn muốn chúng được tiếp xúc với thế giới bên ngoài. Trong hầu hết các trường hợp, chúng là các thực thể phẳng mà không nhất thiết phải có cùng cấu trúc với các thực thể cơ sở dữ liệu của bạn.

Đây là trách nhiệm của lớp dịch vụ của bạn để sử dụng kinh doanh/lớp dữ liệu và xây dựng của DTO mà bạn tiếp xúc với thế giới bên ngoài.

Những gì bạn sử dụng trong lớp dữ liệu và doanh nghiệp của mình tùy thuộc vào kiến ​​trúc. Bạn có thể có một mô hình miền được ánh xạ với mã đầu tiên. Trong trường hợp đó, lớp dịch vụ ánh xạ các thực thể miền tới các hợp đồng dữ liệu (DTO). Nếu bạn không có một mô hình miền (mô hình thiếu máu), thì bạn cũng có thể chỉ ánh xạ cơ sở dữ liệu trực tiếp đến DTO của bạn.

Các ASP.NET MVC trang web tiêu thụ dịch vụ, và ánh xạ của DTO nó nhận được để dành xem các mô hình mà sau đó được thông qua để xem cụ thể.

Ngoài ra, bạn cũng có thể quyết định chia tách truy vấn từ các lệnh. Đây là một cách tiếp cận tốt bởi vì các DTO của bạn nhận được trở lại như reqult của một truy vấn là hoàn toàn khác với các lệnh mà bạn gửi đến dịch vụ. Lệnh chỉ chứa những gì cần thiết để thực hiện lệnh và chứa doanh nghiệp có ý định những gì bạn muốn đạt được, trong khi truy vấn trả về một mô hình phẳng về những gì bạn cần trong giao diện người dùng.

nhận xét khác:

  • Không để các đối tượng cơ sở dữ liệu của bạn.
  • Không chuyển đổi trong lớp doanh nghiệp, vì nó không phải là logic nghiệp vụ.
+4

Tôi hoàn toàn không đồng ý với điểm đạn cuối cùng. Chuyển đổi thành dto từ thực thể tên miền thường là logic nghiệp vụ. Lớp dữ liệu sẽ truy cập, duy trì và trả về các đối tượng miền. Các bll nên quyết định những gì để trở lại giao diện người dùng tùy thuộc vào biến trang hiện tại, quy tắc kinh doanh, vv Bạn không muốn lớp dữ liệu của bạn đưa ra quyết định dựa trên logic kinh doanh nó cần phải là câm và lỏng lẻo cùng nhau càng tốt. – TheMook

+0

Không sao đâu :) Tuy nhiên, ánh xạ logic với tôi không thuộc về lớp nghiệp vụ, vì ánh xạ có thể khác nhau tùy thuộc vào hoạt động dịch vụ được gọi, trong khi logic nghiệp vụ là như nhau; do đó ánh xạ này thuộc về lớp dịch vụ. –

+0

Ah, báo trước của bạn có "nơi có một lớp dịch vụ" và OP chỉ định 3 lớp mà không có một lớp dịch vụ riêng biệt, do đó tôi đã làm việc từ quan điểm rằng BLL chứa lớp dịch vụ. Có, trong kiến ​​trúc bạn mô tả, tôi đồng ý rằng lớp dịch vụ là nơi. Với cấu trúc của OP, tôi nghĩ bạn đã ủng hộ việc sử dụng DAL. – TheMook

1

Tôi sử dụng dự án có tên Được chia sẻ cho các mục đích như vậy, để chia sẻ đối tượng với tất cả các lớp. Bất kể tên, nó sẽ được hiển thị bởi tất cả các lớp.

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