首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 共享數據契約命名空間衝突問題與解決方案

     編輯:關於.NET

問題場景

專案中發現同一數據契約在客戶端屬於兩個不同命名空間,導致兩服務交互時類型不匹配,互操作性差,需額外拆裝轉換。以下重現場景:

實體類 (命名空間: GaryChenWCFService)

namespace GaryChenWCFService {
    public class Customer {
        public string Name { get; set; }
        public string Sex { get; set; }
    }
}

服務 1:返回 Customer

namespace GaryChenWCFService.ServiceClasses {
    public class OneCustomerService : ServiceContracts.IOneCustomer {
        public GaryChenWCFService.Customer GetCustomer() { /*...*/ }
    }
}

服務 2:接收 Customer

namespace GaryChenWCFService.ServiceClasses {
    public class TwoCustomerService : ServiceContracts.ITwoCustomer {
        public void AddCustomer(GaryChenWCFService.Customer cs) { /*...*/ }
    }
}

客戶端調用困境


OneCustomerService_Proxy.OneCustomerClient OneService_Proxy = new ...();
TwoCustomerService_Proxy.TwoCustomerClient TwoService_Proxy = new ...();
OneCustomerService_Proxy.Customer cu = OneService_Proxy.GetCustomer();
TwoService_Proxy.AddCustomer(cu); // 編譯錯誤:類型不匹配

服務 1 返回的 Customer 屬於 OneCustomerService_Proxy 命名空間,服務 2 期望 TwoCustomerService_Proxy.Customer。雖代表同一數據契約,但代理生成的類型不同(見物件瀏覽器截圖),須顯式轉換,極不便利。

代理 1 生成類型 代理 2 生成類型

官方解釋與最佳實踐

《WCF 編程第二版》指出:VS 2008 添加服務引用時,必須為每個引用提供唯一命名空間。若兩服務共享相同數據契約,會得到兩個不同命名空間的類型。預設情況下,若客戶端引用的任意程序集包含與服務元數據匹配的數據契約,VS 不會重新導入。**關鍵限制:已有的數據契約引用必須在另一個被引用程序集中,而非客戶端專案本身。**

最佳實踐:將所有共享數據契約分解到專門類庫,讓所有客戶端引用該程序集。然後在服務引用的「進階設定」對話框中,勾選「Reuse types in referenced assemblies」(預設勾選),控制引用程序集與共享數據契約協調。單選按鈕可限制跨所有引用程序集重用或特定程序集。注意:只能共享數據契約,不能共享服務契約。

實際操作步驟

  1. 將服務端實體類庫 (DLL) 部署至客戶端可訪問位置。
  2. 客戶端專案添加對該 DLL 的引用。
  3. 添加服務引用時,在「進階設定」確保「Reuse types in referenced assemblies」勾選,並指定共享類型所在程序集(見截圖)。
  4. 進階設定對話框

吐槽與期待

這做法需將服務端 DLL 分發給客戶端,對異構平台調用極不合理。但若客戶端同為 .NET 自主開發,這是無奈之舉。期待 WCF 未來版本改進此點!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved