2010-12-03 73 views
0

我正在研究一個簡單的插件框架。 WCF客戶端需要創建一個「ISubject」實例,然後發送回服務端。 'ISubject'可以由用戶擴展。客戶端在運行時唯一知道的是'ISubject'子類的ID。WCF服務可否傳輸類型(客戶端不知道此類型)信息?

首先,客戶端需要獲取'ISubject'特定子類的類型信息。其次,客戶端使用反射枚舉所有成員來創建一個自定義屬性編輯器,以便每個成員可以被賦值並賦予適當的值。最後,客戶端創建該子類的一個實例併發送回服務。

問題是客戶端如何通過WCF通信獲取類型信息?

我不希望客戶端加載該子集('ISubject')存在的程序集。

感謝

+0

這聽起來不太有希望。你真的想要解決什麼問題? – spender 2010-12-03 03:01:31

+1

不,你不能這樣做 - WCF是關於**序列化的**(XML)消息 - 你不能通過線路發送未知對象類型,並在客戶端重新組裝它們而不知道它們...... WCF是** NOT **「對象遠程」類型的系統(如DCOM或CORBA) - 通過設計 – 2010-12-03 05:40:08

+0

Spender,我定義了一個接口ISubject,它可以被插件框架用戶擴展。框架(在服務器端運行)可以在運行時從第三方程序集加載ISubject的子類。客戶端需要創建一個擴展子類的實例併發送回服務器端。我使用WCF進行服務器和客戶端之間的通信。所以,問題是客戶端如何獲取類型信息來創建子類的實例(我使用反射,因此需要類型信息)。注意:我不想讓客戶端加載第三方程序集。 – 2010-12-03 06:58:31

回答

3

首先,您需要知道,WCF將在您描述的場景中向您的客戶端提供任何類型的信息。如果你打算這樣做,你必須自己提供一個機制。

接下來,瞭解WCF並不真正將對象從服務器傳遞到客戶端,反之亦然。它所傳遞的都是XML資訊。通常,傳遞的XML信息集包含發送方一側存在的某個對象的序列化表示;在這種情況下,如果客戶知道該類型(即,可以從它的程序集中加載類型的元數據),它可以反序列化XML以在客戶端實例化一個相同的對象。如果客戶端沒有類型元數據,則不能:這是WCF的正常情況,除非數據協定類型在服務器和客戶端實現共享的程序集中(通常不是一個好主意)。

通常使用WCF的方式(例如,如果客戶端是在Visual Studio中使用「服務引用」實現的),會發生什麼情況是服務發佈描述其操作的WSDL元數據以及操作參數的XML模式,返回值,並從中生成一組類型以供客戶端實現使用。這些與服務實現使用的數據協定類型不同,但是它們是「等價的」,因爲它們可以被序列化爲通過網絡傳遞的相同的XML數據。通常,這種類型的生成是在Visual Studio的設計時完成的。

爲了做你正在做的事情,這本質上是在運行時進行這種類型的生成,你將需要一些機制,通過這種機制客戶機可以充分了解代表各種類型的XML的結構對象實現ISubject,以便它可以理解從服務接收到的XML並生成服務期待的適當的XML(或者直接使用XML,或者以某種方式對它進行反序列化/序列化)。如果你真的想這樣做,可能的方式可能是:

  • 出帶外的一些機制,使客戶端是預先配置了對應ISubject的每個子類,它可能會看到相關的類型信息。在blindmeis的答案中提供的鏈接是一種方法。

  • 提供了一個單獨的服務操作,通過該操作,客戶端可以將子類的ID轉換爲子類的類型元數據(可能是XSD模式,客戶端可以從中生成合適的可序列化的.NET類型來往返XML )。

  • 原則上,服務在包含序列化對象的響應頭部以某種格式傳遞類型元數據也是可行的。客戶需要以適當的方式閱讀,解釋和處理類型信息。

無論哪種方式,這將是很多努力,而不是使用WCF的標準方式。你將不得不決定是否值得。

0

反序列化對象的接收方需要有該類型是在定義的彙編。

也許你應該考慮一些類型的遠程或代理設置的地方ISubject實例住在一邊和另一邊回電。如果您需要通過線路編組大量數據,這可能會有問題。

+0

我完全是WCF的新手。你可以更具體嗎? – 2010-12-03 03:17:38

+0

我對WCF沒有太多的經驗,但一般的問題是「我有一個可以在一臺機器或進程上實例化的類型,我需要在另一臺機器上使用它」。要搜索的關鍵字是Remoting,MarshalByRefObject和遠程過程調用。 – 2010-12-03 03:29:37

1

我想你可能會失去了一些東西:)

與Web服務的一個非常重要的概念和WCF是,我們可以通過我們的對象通過網絡,客戶端可以使用相同的對象作爲服務器的工作。此外,當客戶端在Visual Studio中添加服務引用時,服務器將向客戶端發送所需的所有詳細信息,以瞭解將通過網絡傳遞的任何類型。

應該沒有必要反思。

有很多覆蓋,但我建議在開始使用此教程涵蓋WCF DataContracts - http://www.codeproject.com/KB/WCF/WCFHostingAndConsuming.aspx

0

WCF需要知道應該通過線路發送的真實對象(不是一個接口!)。所以你必須滿足服務器和WCF服務的clientproxy方面,他們知道類型。如果您在創建WCF服務時不知道對象類型,則必須找到一種以動態方式執行此操作的方法。我使用here的解決方案將knownTypes獲取到我的WCF服務。

[ServiceContract(SessionMode = SessionMode.Required] 
[ServiceKnownType("GetServiceKnownTypes", typeof(KnownTypeHelper))]//<--!!! 
public interface IWCFService 
{ 
    [OperationContract(IsOneWay = false)] 
    object DoSomething(object obj); 
} 

,如果你有什麼「萬能」像上面的代碼,你必須確保在運行時無論你的目標將是,WCF服務必須知道這個對象。

你寫你的客戶端創建一個子類並將其發送回服務。如果你想這樣做,WCF(clientproxy和server!)需要知道你的子類的真實類型。

相關問題