Part I 已完成服務端 Contract 繼承體系:IFullWhetherForecast : ISimpleWhetherForecast,服務類別 FullWhetherForecastService : SimpleWhetherForecastService。僅暴露最底層 Contract 端點。現須在客戶端重建同樣的繼承架構,而非接受扁平化的產生式 Proxy。
但遺失原始類別的 ToString() 覆寫 — 代碼產生器僅處理資料成員。
產生單一 IFullWhetherForecast 包含所有 Operation,喪失繼承階層。
FullWhetherForecastClient 直接實作扁平 Contract,無繼承關係。
// ISimpleWhetherForecast.cs
[ServiceContract]
public interface ISimpleWhetherForecast
{
[OperationContract] BasicWhetherInfo GetBasicWhetherInfo(string postalcode);
}
// IFullWhetherForecast.cs
[ServiceContract]
public interface IFullWhetherForecast : ISimpleWhetherForecast
{
[OperationContract] WindInfo GetWindInfo(string postalcode);
}
避免重複定義,確保序列化一致性。
<endpoint address="https://localhost/.../FullWhetherForecastService.svc"
binding="wsHttpBinding"
contract="Artech.InheritanceHierarchy.Client.IFullWhetherForecast" />
// SimpleWhetherForecastClient.cs
public class SimpleWhetherForecastClient : ClientBase<IFullWhetherForecast>, ISimpleWhetherForecast
{
public BasicWhetherInfo GetBasicWhetherInfo(string postalcode) => Channel.GetBasicWhetherInfo(postalcode);
}
// FullWhetherForecastClient.cs
public class FullWhetherForecastClient : SimpleWhetherForecastClient, IFullWhetherForecast
{
public WindInfo GetWindInfo(string postalcode) => Channel.GetWindInfo(postalcode);
}
using (var simple = new SimpleWhetherForecastClient())
{
var basic = simple.GetBasicWhetherInfo("10001");
}
using (var full = new FullWhetherForecastClient())
{
var basic = full.GetBasicWhetherInfo("10001"); // 繼承自基底 Proxy
var wind = full.GetWindInfo("10001");
}
ISimpleWhetherForecast,不受完整功能變更影響。WCF 不強制客戶端接受扁平化 Proxy。透過 ClientBase<T> 泛型參數指定最底層 Contract,配合 C# 介面繼承與類別繼承,即可在客戶端重建豐富的 OO 架構,實現 SOA 服務契約與 OOP 程式模型的完美融合。