Có vẻ như bạn đang cố gắng sử dụng SOA để truy cập từ xa mô hình đối tượng của bạn. Bạn sẽ tốt hơn khi xem xét các tương tác và khả năng mà bạn muốn dịch vụ của mình hiển thị và tránh phơi bày chi tiết thừa kế của việc triển khai dịch vụ của bạn.
Vì vậy, trong trường hợp này, nơi bạn cần một danh sách các tài khoản người dùng giao diện của bạn sẽ giống như
[ServiceContract]
interface ISomeService
{
[OperationContract]
Collection<AccountSummary> ListAccountsForUser(
User user /*This information could be out of band in a claim*/);
}
[DataContract]
class AccountSummary
{
[DataMember]
public string AccountNumber {get;set;}
[DataMember]
public string AccountType {get;set;}
//Other account summary information
}
nếu bạn quyết định đi xuống con đường thừa kế, bạn có thể sử dụng KnownType attribute, nhưng lưu ý rằng điều này sẽ thêm một số loại thông tin vào tin nhắn được gửi qua dây mà có thể giới hạn khả năng tương tác của bạn trong một số trường hợp.
Cập nhật:
tôi là một chút giới hạn cho thời gian trước khi tôi trả lời, vì vậy tôi sẽ cố gắng và xây dựng trên lý do tại sao tôi thích phong cách này.
Tôi sẽ không khuyên bạn để lộ OOAD thông qua DTO trong một lớp riêng biệt, điều này thường dẫn đến giao diện cồng kềnh nơi bạn truyền tải rất nhiều dữ liệu không được sử dụng và phân loại bản đồ của mô hình miền của bạn với tất cả logic đã bị xóa và tôi không thấy giá trị. Tôi thường thiết kế lớp dịch vụ của mình xung quanh các hoạt động mà nó hiển thị và tôi sử dụng các DTO để định nghĩa các tương tác dịch vụ.
Sử dụng DTO dựa trên hoạt động được hiển thị và không phải trên mô hình miền giúp giữ gói dịch vụ và giảm khớp nối với mô hình miền. Bằng cách không phơi bày mô hình miền của mình, tôi không phải thực hiện bất kỳ thỏa hiệp nào về khả năng hiển thị trường hoặc thừa kế vì lợi ích của việc tuần tự hóa.
ví dụ nếu tôi đã phơi bày một phương pháp chuyển từ một tài khoản khác giao diện dịch vụ sẽ giống như thế này:
[ServiceContract]
interface ISomeService
{
[OperationContract]
TransferResult Transfer(TransferRequest request);
}
[DataContract]
class TransferRequest
{
[DataMember]
public string FromAccountNumber {get;set;}
[DataMember]
public string ToAccountNumber {get;set;}
[DataMember]
public Money Amount {get;set;}
}
class SomeService : ISomeService
{
TransferResult Transfer(TransferRequest request)
{
//Check parameters...omitted for clarity
var from = repository.Load<Account>(request.FromAccountNumber);
//Assert that the caller is authorised to request transfer on this account
var to = repository.Load<Account>(request.ToAccountNumber);
from.Transfer(to, request.Amount);
//Build an appropriate response (or fault)
}
}
bây giờ từ giao diện này nó là rất rõ ràng đối với conusmer những gì các dữ liệu cần thiết để gọi thao tác này là. Nếu tôi đã triển khai điều này là
[ServiceContract]
interface ISomeService
{
[OperationContract]
TransferResult Transfer(AccountDto from, AccountDto to, MoneyDto dto);
}
và tài khoảnDưới là bản sao của các trường trong tài khoản, là người tiêu dùng, tôi nên điền vào các trường nào? Tất cả bọn họ? Nếu một thuộc tính mới được thêm vào để hỗ trợ một hoạt động mới, tất cả người dùng của tất cả các hoạt động bây giờ có thể thấy thuộc tính này. WCF cho phép tôi đánh dấu tài sản này là không bắt buộc để tôi không phá vỡ tất cả các khách hàng khác của mình, nhưng nếu nó là bắt buộc đối với hoạt động mới, khách hàng sẽ chỉ tìm ra khi họ gọi cho hoạt động.
Tệ hơn nữa, với tư cách là người triển khai dịch vụ, điều gì xảy ra nếu họ đã cung cấp cho tôi số dư hiện tại? tôi có nên tin tưởng không?
Quy tắc chung ở đây là hỏi ai sở hữu dữ liệu, khách hàng hoặc dịch vụ? Nếu khách hàng sở hữu nó, thì nó có thể chuyển nó cho dịch vụ và sau khi thực hiện một số kiểm tra cơ bản, dịch vụ có thể sử dụng nó. Nếu dịch vụ sở hữu nó, khách hàng chỉ nên chuyển đủ thông tin cho dịch vụ để truy xuất thông tin cần thiết. Điều này cho phép dịch vụ duy trì tính nhất quán của dữ liệu mà nó sở hữu.
Trong ví dụ này, dịch vụ sở hữu thông tin tài khoản và khóa để định vị nó là số tài khoản. Mặc dù dịch vụ có thể xác thực số tiền (là số tiền dương, tiền được hỗ trợ, v.v.) do khách hàng sở hữu và do đó chúng tôi hy vọng tất cả các trường trên DTO sẽ được điền.
Tóm lại, tôi đã thấy nó được thực hiện theo 3 cách, nhưng thiết kế DTO xung quanh các hoạt động cụ thể đã đạt được thành công nhất cả từ triển khai dịch vụ và người tiêu dùng. Nó cho phép các hoạt động phát triển độc lập và rất rõ ràng về những gì được mong đợi bởi dịch vụ và những gì sẽ được trả lại cho khách hàng.
Nếu đây là bài tập về nhà, vui lòng gắn thẻ như vậy. –
@HenkHolterman Nó không phải là một bài tập về nhà. Tôi được phân bổ vào một dự án mới sử dụng SOA. Mặc dù trước đây tôi đã sử dụng WCF, nhưng nó không sử dụng SOA. Tôi đang cố gắng tìm hiểu các khái niệm SOA. – Lijo