2011-11-15 33 views
7

Tôi muốn biết thực hành tốt nhất trong việc thiết kế các nhà thầu của các đối tượng DTO là gì.C# Dto xây dựng và phụ thuộc tiêm

nói tôi có một đối tượng dto như thế này:

class CustomerDto 
{ 
    public string Name { get; set; } 
    public string Surname { get; set; } 
    public string Phone { get; set; } 
    ... 
} 

Có một số cách để xây dựng các đối tượng:

tôi có thể tuyên bố một constructor:

public CustomerDto(string name, string surname, string phone, ...) 
{ 
    this.Name = name; 
    this.Surname = surname; 
    this.Phone = phone; 
    ... 
} 

Khi bạn thấy điều này nhà xây dựng và ngay lập tức kết luận vi phạm SRP (Trách nhiệm một người)?

Mặc dù các thuộc tính này đều liên quan. Một số cũng có thể lập luận rằng không cần phải xác thực các thuộc tính vì đây là một DTO và có hành vi NO, và hành vi thay vì phải nằm trên đối tượng miền mà nó ánh xạ từ đó.

Trong C# chúng ta cũng có thể thanh lịch hơn xây dựng đối tượng này:

var dto = new CustomerDto() 
{ 
    Name = "Some name", 
    Surname = "Some surname" 
} 

Hoặc sử dụng một người thợ xây thạo hoặc một khuôn khổ như NBuilder.

Ngoài ra còn có việc sử dụng các khung bản đồ tự động như Automapper. Vấn đề cũng là sử dụng một thùng chứa Ioc, ctor trở nên phức tạp, cũng như rủi ro trong việc hoán đổi các đối số chẳng hạn, bạn chuyển tên họ hoặc ngược lại, việc xác thực có thể bỏ qua việc lập bản đồ rõ ràng dễ dàng hơn như trên.

Hãy giúp thuyết phục tôi đó là cách tốt hơn.

+0

bản sao có thể có của [Dependency Injection - sử dụng với các đối tượng chuyển dữ liệu (DTO)?] (Http: // stackoverflow.com/questions/6297322/dependency-injection-use-with-data-transfer-objects-dtos) –

+0

Tôi đã gặp vấn đề tương tự này, và quyết định chống lại các nhà xây dựng .. Vì một lý do đơn giản: sau, trong một tháng, hoặc 6 tháng, bản thân tôi hoặc người khác sẽ xem xét điều này và phải suy nghĩ về nó theo cùng một cách bản thân mình (và bản thân bạn) đang suy nghĩ bây giờ. Tôi đã tìm thấy suy nghĩ trong khi đọc mã là một dấu hiệu cho thấy nó quá phức tạp. – dferraro

Trả lời

10

Các loại giá trị như trong ví dụ của bạn không phụ thuộc. Một phụ thuộc cung cấp một chức năng (hoặc cấu hình) cho người tiêu dùng. Trong trường hợp của bạn, chúng chỉ là các giá trị bình thường được gán cho DTO của bạn. Miễn là dữ liệu thuộc về nhau, bạn không vi phạm SRP ngay cả khi bạn chỉ định nhiều giá trị trong hàm tạo. Trách nhiệm duy nhất trong trường hợp này là giữ dữ liệu.

Cũng không nên tạo DTO bởi vùng chứa IoC và không có phụ thuộc thực sự. Bạn nên tạo chúng theo cách thủ công, bằng khung kiên trì hoặc sử dụng ánh xạ tự động.

Nếu gán giá trị bằng cách sử dụng hàm tạo hoặc thuộc tính thì tốt hơn tùy thuộc vào cách sử dụng. Nếu họ được yêu cầu biến thể constructor là tốt hơn. Nếu chúng là tùy chọn thì cách của thuộc tính tốt hơn.

+0

Những gì tôi thích về câu trả lời này là nó xác nhận những gì tôi mặc dù về một phụ thuộc và rằng những arent thực sự phụ thuộc họ không phải là hệ thống phụ bên ngoài mà bạn muốn một container IOC để thay thế. Ngoài ra, lý do cho tùy chọn 2 là nó thực sự cho phép khung công tác ánh xạ tự động thực hiện điều nó chỉ đơn giản là mang dữ liệu giữa các ranh giới. Tôi đã cảm thấy rằng mối quan tâm của dto yêu cầu nói một đối số tên không phải là một cái gì đó nó thực sự quan tâm? đồng ý? – Andre

3

Tôi khuyên bạn nên sử dụng cấu trúc dữ liệu bất biến để thực thể DTO không lộ bất kỳ trình lắng nghe nào, rõ ràng theo cách này, hàm tạo nên cung cấp khả năng khởi tạo tất cả các thuộc tính cơ bản của một DTO nhất định.

Vì vậy, tôi thích:

public CustomerDto(string name, string surname, string phone, ...) 

DTO là một Object Data Transfer, đặc biệt là đại diện cho một tập hợp các thuộc tính được thông qua trên một hệ thống (phân phối cũng) ranh giới, do đó, không bận tâm quá nhiều về SRP sự vi phạm. Điều này giống như mẫu thiết kế mặt tiền, nó abstarcts một tập hợp các hoạt động/dịch vụ để đơn giản hóa việc sử dụng. Vì vậy, trong kase Keep It Simple thắng này.

+1

Điều tôi đang phân vân là Martin fowler mô tả đối tượng trasnfer dữ liệu như một đối tượng giữ trạng thái và không có hành vi và thực sự desribes nó như là một cách để giảm các cuộc gọi phương thức. Bằng cách giới thiệu các đối số hàm tạo và xác nhận hợp lệ chúng, bạn đang thêm hành vi. Ghi nhớ rằng mục đích là để ánh xạ từ miền tới khung nhìn và việc xác thực xảy ra rất có thể trên đối tượng miền. Vì vậy, các dto thực sự cần phải lo lắng về các đối số và những gì được yêu cầu vì nó chỉ đơn giản là mang dữ liệu ở một nơi khác và xác nhận là một mối quan tâm khác nhau? – Andre

+1

Xác nhận đối số như 'không null' /' không trống rỗng 'không phải là một hành vi đối tượng, hãy xem xét nó giống như công cụ dịch vụ khung ứng dụng của bạn. Nhưng nếu bạn định đóng gói tính hợp lệ như 'if (customerRole == Roles.Vip) IncreaseBonus (x)' - đây sẽ là hành vi thực sự và không nên ở trong DTO, DTO biểu diễn satte FINAL của một đối tượng – sll

+0

Tôi vừa kiểm tra và có vẻ như Automapper là REALLY thông minh, nó sẽ ánh xạ các tên đối số hàm tạo cho các thuộc tính. Vấn đề là mặc dù tôi dường như với tôi rằng nó phụ thuộc vào cách sử dụng, nếu bạn ánh xạ từ một đối tượng miền (đã được xác nhận hợp lệ) đến một khung nhìn (xác nhận hợp lệ) không có lý do gì để tạo các đối số constructor, có vẻ như phương thức khởi tạo đã không có nhược điểm, nhưng tôi có thể thấy một cái lớn. Bạn không thể ngay lập tức phát hiện ra nếu một đối số là cách sai vòng, hoặc trong thực tế những gì tài sản một đối số bản đồ? – Andre

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