WCF 功能強大但配置繁瑣:散落的 config 檔、客戶端需知服務位址、部署維護困難。本文提出 Internal Communication Service (ICS) 架構,透過 ICSFactory 統一服務建立、ServiceLocator 集中位址管理,實現 WCF 服務位置透明化。
IUser userSrv = ICSFactory.Create();
var result = userSrv.GetUserName("1", "2", "3");
ICSFactory.Close(userSrv);
string result = string.Empty;
using (TransactionScope ts = new TransactionScope())
{
IUser userSrv = ICSFactory.Create();
IAdmin adminSrv = ICSFactory.Create();
result = userSrv.GetUserName("1", "2", "3");
result = adminSrv.CheckPermission(100).ToString();
ts.Complete();
ICSFactory.Close(userSrv);
ICSFactory.Close(adminSrv);
}
appSetting 指定路徑:\\fs\root\a2d.service.config
<?xml version="1.0" encoding="utf-8"?>
<A2D>
<ServiceLocator>
<Service ContractNamespace="DEsbInterface" Contract="IUser">
<Url EndpointType="Tcp">net.tcp://192.168.1.100:9999/usersrv</Url>
</Service>
<Service ContractNamespace="DEsbInterface" Contract="IAdmin">
<Url EndpointType="Tcp">net.tcp://192.168.1.100:9998/adminsrv</Url>
</Service>
</ServiceLocator>
</A2D>

public class ICSFactory
{
public static T Create()
{
string contractNamespace = typeof(T).Namespace;
string contract = typeof(T).Name;
// 1. 從 ServiceLocator 取得位址資訊
Location location = ServiceLocator.Locate(contractNamespace, contract);
// 2. 程式碼建立 Binding
NetTcpBinding binding = new NetTcpBinding();
binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
binding.Security.Mode = SecurityMode.None;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
// 3. 交易流程支援
binding.TransactionFlow = true;
binding.TransactionProtocol = TransactionProtocol.OleTransactions;
// 4. 建立通道
EndpointAddress address = new EndpointAddress(location.Url);
T proxy = ChannelFactory.CreateChannel(binding, address);
return proxy;
}
public static void Close(object proxy)
{
if (proxy == null) return;
IDisposable disposable = proxy as IDisposable;
if (disposable != null) disposable.Dispose();
}
}
public static class ServiceLocator
{
private static Dictionary serviceCache = new Dictionary();
// 啟動時載入 XML 到記憶體 (Service、Url 物件)
public static Location Locate(string contractNamespace, string contract)
{
string key = string.Format("{0}.{1}", contractNamespace, contract);
Service srv;
if (!serviceCache.ContainsKey(key))
{
srv = FindService(contractNamespace, contract);
serviceCache[key] = srv;
}
else srv = serviceCache[key];
if (srv.Urls == null || srv.Urls.Count == 0)
throw new Exception(string.Format("Service url not found [{0}.{1}]", contractNamespace, contract));
Url url = srv.Urls.First(); // 可擴展負載平衡邏輯
return new Location { EndpointType = url.EndpointType, Url = url.ReferenceUrl };
}
private static Service FindService(string contractNamespace, string contract, Service srv = null)
{
var matched = LocatorServiceConfiguration.Services
.Where(t => t.Contract == contract && t.ContractNamespace == contractNamespace)
.ToList();
if (matched == null || matched.Count == 0)
throw new Exception(string.Format("Service not found [{0}.{1}]", contractNamespace, contract));
return matched.First();
}
}
| 傳統 WCF | ICS 架構 |
|---|---|
| 每客戶端獨立 config | 中央化單一設定檔 |
| 服務位址硬編碼/分散 | ServiceLocator 動態解析 |
| 部署需同步更新所有客戶端 | 僅更新中央設定,客戶端零感知 |
| Binding 參數分散在 config | 程式碼集中管理、版本控制 |
| 交易流程配置複雜 | Binding 統一啟用 TransactionFlow |
Url 清單支援多端點,Locate 實作輪詢/隨機/加權策略EndpointType 動態建立 Binding查看本欄目