WCF 服務實例化預設由框架控制,難以套用依賴注入(DI)與切面導向程式設計(AOP)。Enterprise Library 提供 Unity(DI 容器) 與 PIAB(Policy Injection Application Block,AOP 框架)。本文示範如何打通三者,實現服務實例由 Unity 管理、攔截器由 PIAB 驅動的完整整合方案。
ExtendedInterception 擴充套件,讓 Unity 建立可攔截的物件,PIAB 依策略注入 CallHandler。IInstanceProvider(UnityInstanceProvider),在 GetInstance 中委派 Unity 解析服務實例。IServiceBehavior/IContractBehavior/IEndpointBehavior 的 UnityIntegrationBehaviorAttribute,將自訂 InstanceProvider 掛載到 DispatchRuntime。Containers 與 registeredTypeMappings 避免重複建立容器與解析映射。contractType、containerName,載入對應 Unity 區段配置。GetInstance 動態註冊「契約介面 → 服務實作類型」映射(若未配置),再 container.Resolve 取得實例。ReleaseInstance 呼叫 IDisposable.Dispose 釋放資源。public class UnityIntegrationBehaviorAttribute : Attribute,
IServiceBehavior, IContractBehavior, IEndpointBehavior
{
public string ContainerName { get; set; }
// 終結點/契約/服務行為統一在此注入 InstanceProvider
public void ApplyDispatchBehavior(ServiceEndpoint ep, EndpointDispatcher ed)
{
ed.DispatchRuntime.InstanceProvider =
new UnityInstanceProvider(ep.Contract.ContractType, ContainerName);
}
// ... 其他介面成員省略
}
[ServiceContract(Namespace="urn:artech.com")]
public interface ISyncTimeProvision { [OperationContract] DateTime GetCurrentTime(); }
[UnityIntegrationBehavior(ContainerName="myContainer")]
public class SyncTimeProvisionService : ISyncTimeProvision
{
[Dependency] public ISyncTimeProvider SyncTimeProvider { get; set; }
public DateTime GetCurrentTime() => SyncTimeProvider.GetCurrentTime();
}
public interface ISyncTimeProvider { DateTime GetCurrentTime(); }
[CachingCallHandler] // PIAB 快取攔截器
public class SyncTimeProvider : ISyncTimeProvider
{
public DateTime GetCurrentTime() => DateTime.Now;
}
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection..."/>
</configSections>
<unity>
<containers>
<container name="myContainer">
<types>
<type type="ISyncTimeProvider" mapTo="SyncTimeProvider" />
</types>
</container>
</containers>
</unity>
<system.serviceModel>
<services>
<service name="SyncTimeProvisionService">
<endpoint address="..." binding="ws2007HttpBinding" contract="ISyncTimeProvision" />
</service>
</services>
</system.serviceModel>
連續呼叫 5 次 GetCurrentTime(間隔 1 秒),輸出時間完全相同,證明 CachingCallHandler 生效,Unity+PIAB+WCF 整合成功。
IInstanceProvider 是 WCF 與 DI 容器整合的核心切入點。