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

Enterprise Library 深入解析與靈活應用(7):再談 PIAB 與 Unity 整合

     編輯:關於.NET

前言

Enterprise Library 中 PIAB(Policy Injection Application Block)定位為輕量級 AOP 框架,Unity 為 IoC 容器。PIAB 透過方法攔截實現策略注入,Unity 則負責依賴注入與物件建立。若能讓 Unity 依照 PIAB 要求建立可攔截物件,即可實現兩者整合。

一、Unity 1.2 與 EntLib 4.1 原生整合

新版本已提供原生整合:透過 Microsoft.Practices.Unity.InterceptionExtension.Interception 擴展實現。範例定義 ISyncTimeServiceProvision 與 SyncTimeServiceProvisionService,後者依賴 ISyncTimeProvider 介面,由 SyncTimeProvider 實作並標註 [CachingCallHandler]。

IUnityContainer container = new UnityContainer();
container.RegisterType<ISyncTimeServiceProvision, SyncTimeServiceProvisionService>();
container.RegisterType<ISyncTimeProvider, SyncTimeProvider>();
container.AddNewExtension<Interception>();
container.Configure<Interception>().SetDefaultInterceptorFor(typeof(ISyncTimeProvider), new TransparentProxyInterceptor());

var service = container.Resolve<ISyncTimeServiceProvision>();
for (int i = 0; i < 5; i++)
{
    Console.WriteLine(service.GetCurrentTime());
    Thread.Sleep(1000);
}

輸出時間相同,證明快取處理器生效,整合成功。

二、自訂 UnityContainerExtension 實現動態攔截器註冊

原生整合需手動為每個需攔截型別註冊 Interceptor,不具擴展性。解決方案:繼承 InstanceInterceptionStrategy 與 TypeInterceptionStrategy,在 PreBuildUp 動態註冊 Interceptor。

public class ExtendedInterception : Interception
{
    public IInterceptor Interceptor { get; internal set; }

    public ExtendedInterception() => this.Interceptor = new TransparentProxyInterceptor();

    protected override void Initialize()
    {
        this.Context.Strategies.Add(new ExtendedInstanceInterceptionStrategy(this), UnityBuildStage.Setup);
        this.Context.Strategies.Add(new ExtendedTypeInterceptionStrategy(this), UnityBuildStage.PreCreation);
        this.Context.Container.RegisterInstance<InjectionPolicy>(typeof(AttributeDrivenPolicy).AssemblyQualifiedName, new AttributeDrivenPolicy());
    }
}

兩個策略類別分別處理實例與型別層級攔截,於 PreBuildUp 判斷型別是否可攔截並自動設定預設 Interceptor。

使用時無需手動註冊:

IUnityContainer container = new UnityContainer();
container.RegisterType<ISyncTimeServiceProvision, SyncTimeServiceProvisionService>();
container.RegisterType<ISyncTimeProvider, SyncTimeProvider>();

ExtendedInterception interception = new ExtendedInterception();
interception.Interceptor = new TransparentProxyInterceptor();
container.AddExtension(interception);

var service = container.Resolve<ISyncTimeServiceProvision>();
// ...

三、透過配置套用 ExtendedInterception

定義 ExtendedInterceptionElement 繼承 UnityContainerExtensionConfigurationElement,支援配置指定 Interceptor 型別:

<unity>
  <containers>
    <container>
      <types>
        <type type="ISyncTimeServiceProvision" mapTo="SyncTimeServiceProvisionService" />
        <type type="ISyncTimeProvider" mapTo="SyncTimeProvider" />
      </types>
      <extensionConfig>
        <add name="extendedInterception" type="Artech.InterceptableUnity.ExtendedInterceptionElement, Artech.InterceptableUnity" interceptor="Microsoft.Practices.Unity.InterceptionExtension.TransparentProxyInterceptor, Microsoft.Practices.Unity.Interception" />
      </extensionConfig>
    </container>
  </containers>
</unity>

程式碼簡化為:

IUnityContainer container = new UnityContainer();
UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
config.Containers.Default.Configure(container);

var service = container.Resolve<ISyncTimeServiceProvision>();
// ...

完整原始碼可供下載參考。

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