隨著 WCF 服務增多,直接「添加服務引用」導致配置分散、代理創建重複、難以統一異常處理。採用工廠模式 + 通道工廠集中管理所有服務代理。
IServices:繼承所有業務接口,作為工廠返回類型。ServiceFactory:緩存代理實例,提供 GetServiceBusiness(endpointName)。ServiceProxyFactory:使用 RealProxy 創建透明代理,攔截調用。 ChannelFactoryCreator:緩存 ChannelFactory,線程安全創建通道。// 1. 統一接口
[ServiceContract]
public interface IServices : IUserService, IOrderService { }
// 2. 服務工廠
public static class ServiceFactory {
static readonly SortedList _cache = new();
public static IServices GetServiceBusiness(string endpointName) {
if (_cache.TryGetValue(endpointName, out var svc)) return svc;
var proxy = ServiceProxyFactory.Create(endpointName);
_cache[endpointName] = proxy;
return proxy;
}
}
// 3. 代理工廠(RealProxy 攔截)
public static class ServiceProxyFactory {
public static T Create(string endpointName) {
return (T)new ServiceRealProxy(endpointName).GetTransparentProxy();
}
}
public class ServiceRealProxy : RealProxy {
readonly string _endpoint;
public ServiceRealProxy(string endpoint) : base(typeof(T)) { _endpoint = endpoint; }
public override IMessage Invoke(IMessage msg) {
var call = (IMethodCallMessage)msg;
var channel = ChannelFactoryCreator.Create(_endpoint).CreateChannel();
try {
var result = call.MethodBase.Invoke(channel, call.Args);
((ICommunicationObject)channel).Close();
return new ReturnMessage(result, call.Args, call.Args.Length, call.LogicalCallContext, call);
} catch (TargetInvocationException ex) {
// 統一異常轉換:FaultException, CommunicationException, TimeoutException...
throw WrapException(ex.InnerException);
} finally {
((ICommunicationObject)channel).Abort();
}
}
}
// 4. 通道工廠緩存
internal static class ChannelFactoryCreator {
static readonly Hashtable _factories = new();
public static ChannelFactory Create(string endpointName) {
if (_factories.ContainsKey(endpointName))
return (ChannelFactory)_factories[endpointName];
var factory = new ChannelFactory(endpointName);
lock (_factories.SyncRoot) _factories[endpointName] = factory;
return factory;
}
}
所有端點配置集中在 app.config <system.serviceModel> 中,客戶端代碼無硬編碼地址。
IServices 接口,而非具體代理類。ChannelFactory 緩存避免重複創建開銷。RealProxy 僅支持介面代理,需服務契約定義為介面。FaultException(業務異常)、CommunicationException(網絡)、TimeoutException 等。Close 或 Abort,防止連接洩漏。此架構適用於中大型 WCF 客戶端項目,實現了「配置驅動、工廠創建、統一攔截」的現代服務調用模式。