2012-04-06 60 views
0

對不起,長期以來的問題擺在首位。我寧願提出一個較短的問題,但這是我可以提供的最嚴格的版本,我可以清楚地解釋我的觀點。在另一個WCF服務中使用WCF服務的DLL引用

我一直在試圖向我們的客戶提供包裝服務,它應該提供多種服務。背後的想法是減少對一次調用的多次調用,並返回其中包含其他關聯對象的單個對象。爲了說明我的觀點,讓我給下面的例子:

比方說,我們有以下服務:

  • MyCompany.Services.Donation
  • MyCompany.Services.Payment
  • MyCompany.Services.PartialPayment

通常情況下,客戶端應該查詢捐贈服務(使用捐款ID)以獲取捐贈信息,然後使用檢索到的捐贈信息,他們應該查詢支付以獲得與支付相關的詳細信息,如果支付是通過多次小額支付完成的,則使用檢索到的支付信息,他們應該查詢PartialPayment服務以獲取特定捐助者的所有捐贈信息。

而是客戶這樣做,我會提供一個包裝服務,接受donationID作爲單個參數,並返回一個類似的類:

[DataContract(Namespace = "http://MyCompany.Services.DonationDetail")] 
public class DonationDetail 
{ 
    [DataMember] 
    public MyCompany.Services.Donation.Record donationRecord; 
    [DataMember] 
    public PaymentDetail paymentDetail;  
} 

[DataContract(Namespace = "http://MyCompany.Services.DonationDetail")] 
public class PaymentDetail 
{ 
    [DataMember] 
    public MyCompany.Services.Payment.Record paymentRecord; 
    [DataMember] 
    public List<MyCompany.Services.PartialPayment.Record> partialPayments; 
} 

所以DonationDetail記錄的實例應該返回所有相關與捐贈有關的信息。

當我在包裝服務中使用這些單獨服務DLL *時,出現了問題,因爲我使用包裝服務傳遞給客戶端的任何類都成爲包裝服務的一部分,客戶端無法立即使用它們檢索的相應類型使用服務引用而不編寫自定義構造方法將一種類型轉換爲另一種類型 - 儘管它們是相同的對象。相反,在原來的命名空間參考類,服務使用下列類類似的東西,現在上面提到的類:

  • DonationDetail.Record -
  • DonationDetail(捐獻記錄我所期望的MyCompany.Services.Donation.Record) .Record1(付款記錄 - 我希望MyCompany.Services.Payment .Record)
  • DonationDetail.Record2(PartialPayment紀錄 - 我希望MyCompany.Services.PartialPayment.Record)

有沒有提供一種方式這樣的界面沒有自定義構造函數?因此,如果他們使用MyCompany.Services.PartialPayment WCF服務的「PartialPayment」命名空間,他們可以在通過包裝服務檢索DonationDetail後執行下面的操作嗎?

PartialPayment.Record partialPayment = dDetailObj.paymentDetail.partialPayments[0]; 

*:不要問我爲什麼不使用服務引用,除非這是問題的原因,因爲該選項給了我其他的問題,我在這一點上)

回答

2

所以我如果你有兩種不同的服務返回同一個對象,並且把它作爲兩個不同的服務引用給客戶端,儘管最終它們就服務而言是最終它們是同一個對象(因爲它們引用相同的DLL),客戶端將它們視爲兩種不同的類型,因此您無法從其中返回對象並將其作爲輸入發送給其他服務。

假設我明白你的問題(和我道歉,如果我沒有)......

可能地圖一類的其他通過構建並設置屬性,但就是有種真的疼痛和不太友好的消費者等,因此我會建議一些激進的......

溝渠服務引用在客戶端上。

是的,我說了,爲什麼我會建議這樣的事情!?!這裏的原因...

首先,我會確保我的項目結構是這樣的:

捐贈詳細客戶端庫

  • IDonationService(這是服務合同 - 沒有通知在客戶端庫實現)
  • DonationRecord

付款明細客戶端庫

  • IPaymentService(這是服務合同 - 注意在客戶端庫中沒有實現)
  • PaymentRecord

部分支付客戶端庫

  • IPartialPaymentService(這是服務合同 - 通知客戶端沒有實現庫)
  • PartialPaymentRecord

包裝服務客戶端庫(引用其他三個客戶端庫)

  • IWrapperService(這是服務合同 - 注意在客戶端庫中沒有實現)

順便說一句,我給你的記錄不同的類名,但你可以使用命名空間如果你喜歡,並把它們全部叫做Record(我認爲叫他們不同的名字就不那麼容易混淆了,但那可能就是我)。

在服務端,您可以參考您需要實施服務的客戶端庫,並像往常一樣執行所需的任何操作。

在您引用客戶libary客戶端(或庫取決於你想要什麼樣的服務調用)也以同樣的方式(這樣你就有效地具有服務器和客戶端之間共享庫 - 是啊舊派,但嘿,你會看到爲什麼)。

客戶端然後具有服務合同和所有數據合同的接口,所以它不需要整個服務引用,生成代碼的東西。相反,你可以在客戶端上做的是這樣的:

DonationRecord donation; 

using (var cf = new ChannelFactory<IDonationService>("EndpointNameInConfigurationFile")) 
{ 
    IDonationService donationservice = cf.CreateChannel(); 
    donation = donationservice.GetDonation("Donation1234"); 
} 

using (var cf = new ChannelFactory<IWrapperService>("EndpointNameInConfigurationFile")) 
{ 
    IWrapperService wrapperService = cf.CreateChannel(); 
    wrapperService.DoSomethingWithDonation(donation); 
} 

喏,你看我把數據契約從一個服務,並將其發送到一個完全無關的服務,它看起來自然(我有一個對象,從類X上的一個方法返回,我接受它並將它作爲Y類的一個補充,完成了工作,就像編程一樣)。

注意:使用這種技術將不會從剛剛停止工作服務引用因爲他們總是有那麼任何現有的客戶端代碼就不會改變,只是如果你使用新的包裝服務,你可以使用它像這樣省去了映射類型。

+0

嗨kmp,我會回答你的回覆,但我的工作讓我推遲,因爲我想闡述一些你的建議,並在嘗試之前進行嘗試。在此期間,我想感謝你的時間。 – Ferhat 2012-04-11 15:46:57