2009-08-26 47 views
7

Câu hỏi trong tiêu đề ... Tóm lại - Tôi có một dịch vụ WCF trưng bày các hoạt động trả về các lớp thực thể. Các lớp phía máy khách kế thừa từ một lớp cơ sở trừu tượng thay vì System.Object mặc định. Lớp cơ sở trừu tượng có một hàm tạo mặc định được định nghĩa. Khi gọi một trong các phương thức dịch vụ, tôi mong rằng hàm tạo sẽ được gọi khi bộ nối tiếp datacontract hiện thực hóa các đối tượng được trả về. Tuy nhiên, hàm tạo không được gọi. Nếu mặt khác, tôi tạo một cá thể của lớp thực thể, sau đó hàm tạo lớp trừu tượng được gọi.Tại sao hàm tạo lớp cơ sở trừu tượng của tôi không được gọi khi một đối tượng được khởi tạo bởi trình gỡ rối WCF?

Tại sao, oh tại sao và có cách giải quyết khác không? Hoặc tôi đã bỏ lỡ một cái gì đó - là có một chữ ký constructor được gọi bởi serializer datacontract khi materializing đối tượng? Nếu không, làm thế nào có thể bộ nối tiếp datacontract vật hoá các đối tượng mà không cần gọi các nhà xây dựng theo cùng một cách mà một cuộc gọi "SomeClass() mới" sẽ làm gì? Hay tôi đã uống quá nhiều cà phê hôm nay (chỉ có 2 hoặc 3 ly cho đến nay)?

Trả lời

11

WCF (và DataContractSerializer nói riêng) không sử dụng hàm tạo. Không, thực sự (nó sử dụng FormatterServices.GetUninitializedObject để tạo các đối tượng thô). Dự kiến ​​tất cả dữ liệu sẽ được khởi tạo bởi bộ nối tiếp hoặc cho các trường không được tuần tự hóa - bằng các lần gọi lại tuần tự mà bạn thêm vào (ví dụ, thông qua [OnDeserialized]).

+1

Cảm ơn câu trả lời nhanh. Wow. Điều đó làm tôi ngạc nhiên. Tôi nghĩ rằng tất cả các khởi tạo đối tượng sẽ dẫn đến các nhà thầu được gọi. Ồ, tôi đã học được điều gì đó mới mẻ hôm nay ... :) – KristoferA

+0

Nó thực sự khá đáng ngạc nhiên. Tôi đã phải đào xung quanh trong phản xạ lần đầu tiên tôi nhìn thấy nó! –

+0

Câu hỏi tiếp theo [tò mò] sẽ là: _why_ họ đã làm theo cách đó? Hiệu suất? Để gây rối với đầu của chúng tôi? Hoặc một số lý do khác tốt hơn? :) – KristoferA

1

Tôi hoàn toàn hiểu lý do, tuy nhiên tôi không hiểu tại sao họ không hỗ trợ gọi lại tuần tự hóa trong Silverlight. Dường như với tôi, trong giao tiếp WCF - Silverlight, tôi không thể khởi tạo hợp đồng dữ liệu của mình mà không tự hack bản thân mình. Vì vậy, nếu tôi đã có một thành viên tư nhân trong lớp cơ sở của tôi để sử dụng nội bộ (. Ví dụ như undo-redo hành vi), không thể sử dụng constructor mặc định:

Stack<PropertyChange> UndoStack = new Stack<PropertyChange>(); 

này chỉ đơn giản không hoạt động. Để làm cho nó hoạt động tôi nên viết một cái gì đó như thế này:

Stack<PropertyChange> _UndoStack; 
Stack<PropertyChange> UndoStack 
{ 
    get 
    { 
      return _UndoStack == null ? (_UndoStack = new Stack<PropertyChange>()) : _UndoStack; 
    } 
} 

Có vẻ như một cách giải quyết cho tôi. Bất cứ ai có ý tưởng tốt hơn?

+0

Điều này có vẻ như một cách giải quyết, nhưng bạn phải đảm bảo rằng không có điều kiện chủng tộc giữa kiểm tra null và setter hoặc người nào khác bạn có thể trả về Stack cũ cho một luồng. Cách duy nhất tôi biết để giải quyết vấn đề này ít nhất là sử dụng OnDeserializing, tạo một đối tượng 'object syncRoot = new object()' và khóa nó trong trình thu thập UndoStack (hoặc trực tiếp tạo cá thể UndoStack trong phương thức này. – eFloh

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