2012-10-24 208 views
1

我想阻止我的客戶端通過構造函數實例化實體。 由於創建這些實體需要相當多的插入操作(初始化狀態,集合等),而WCF不能這樣工作,所以我想強制他們在服務器端調用一個方法,創建實體,並把它通過線路,像使實體的構造函數私有

客戶端:

var client = EntityServiceClient("myEndpoint"); 
var newEntity = client.CreateEntity(); 

服務器端:

public Entity CreateEntity() 
{ 
    return new Entity(); 
} 

我有什麼工作,但我想以某種方式拋出一個異常當enti的默認構造函數ty被使用,或者是私人的。所以下面不應該工作

客戶端:

var client = EntityServiceClient("myEndpoint"); 
var newEntity = new Entity(); 

有什麼事情可能嗎?

+0

我不完全理解這個問題。你可以說得更詳細點嗎? =( – Gaspa79

+0

使你的實體類變得私人化 –

+0

一個類不需要默認的ctor,你可以使用內部的ctor – Paparazzi

回答

2

這不是真的怎麼WCF的設計工作,序列化對象至於客戶而言只包含數據未行爲,以便你應該發回DTO的不是實體。

但是,如果你堅持採用這種方法,這很可能會在將來給你帶來麻煩,你可以將你的對象服務接口移動到一個單獨的類庫中並分發它,而不是讓客戶端從元數據中生成代碼添加服務引用時。

+0

完全看到你的觀點,而事實上那不是我想要的方式。 – Seb

1

客戶端的類通常是生成的代理。與服務器端不同,只是一個模擬。

在任何情況下,客戶端的解串器都需要能夠重新創建實體。 DataContractSerializer只是簡單地忽略你的私有構造函數並創建它自己的構造函數。

當您使用具有共享類型的庫時,情況稍有變化。那麼你可以做的最好的方法就是製作文件internal並將Factory添加到庫中。

總而言之,我認爲這不是一個好主意。 Remmber,他WCF的目標是交換數據,而不是對象

+0

這不完全準確,雖然它不會調用你的構造函數,但它本身並不實際創建一個它調用FormatterServices.GetUninitializedObject(type)來創建實例,而不調用構造函數或字段初始化器。 –

+0

@TrevorPilley - 客戶端代碼將能夠執行'var p = new ClassWithPrivateCtor();'。 –

+0

是的,如果這些類是從元數據中產生的,那麼我並不是在暗示我正在糾正您關於數據協定序列化程序創建它自己的構造函數的陳述。 –

0

你的問題對我來說真的不清楚 - 無論如何,我會盡力幫助你並給你一些提示。 就你而言,我認爲一種工廠是一種好方法。在服務器端組件中定義EntityServiceClientEntity。注意,訪問修飾符,這裏將防止Entity的實例化通過構造函數:

public class EntityServiceClient 
{ 

    public EntityServiceClient(string endpoint) 
    { 
     // put here initializing code for your service client. 
    } 

    public Entity CreateEntity() 
    { 
     return new Entity(); // May here put your complexe code to initializing a new valid entity 
    } 
} 

public class Entity 
{ 
    internal Entity() 
    { 

    } 
} 
+0

但是,這應該是服務器還是客戶端工廠?或兩者? –

+0

這取決於客戶端 - 服務器的體系結構。在這個問題上,它真的不清楚哪裏是什麼... –

+0

對不起,我的代碼不清楚,我錯過了一個「新」創建的客戶端應該讀取'var client = new EntityServiceClient(「endpointName」);' 我醉了那一天...... – Seb