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

Enterprise Library 深入解析與靈活應用(1):透過 Unity Extension 整合 Policy Injection Application Block

     編輯:關於.NET

前言

Enterprise Library 為微軟 P&P 開源框架,本系列側重深層實作原理、設計模式、擴展與最佳實踐。首篇探討如何透過自訂 UnityContainerExtension 實現 Unity 與 PIAB 整合。

1. 建立 PolicyInjectionStrategy

PIAB 基於 Remoting 方法攔截實現 AOP,需透過 PolicyInjector 建立物件。Unity 建立於 ObjectBuilder 之上,採策略導向物件建立。自訂 BuilderStrategy 在建立前後注入政策:

public class PolicyInjectionStrategy : EnterpriseLibraryBuilderStrategy
{
    public override void PreBuildUp(IBuilderContext context)
    {
        base.PreBuildUp(context);
        if (context.Policies.Get<IPolicyInjectionPolicy>(context.BuildKey) == null)
            context.Policies.Set<IPolicyInjectionPolicy>(new PolicyInjectionPolicy(true), context.BuildKey);
    }

    public override void PostBuildUp(IBuilderContext context)
    {
        base.PostBuildUp(context);
        var policy = context.Policies.Get<IPolicyInjectionPolicy>(context.BuildKey);
        if (policy != null && policy.ApplyPolicies)
        {
            policy.SetPolicyConfigurationSource(EnterpriseLibraryBuilderStrategy.GetConfigurationSource(context));
            context.Existing = policy.ApplyProxy(context.Existing, BuildKey.GetType(context.OriginalBuildKey));
        }
    }
}

PreBuildUp 加入 Policy,PostBuildUp 透過 ApplyProxy(內部呼叫 PolicyInjector.Wrap)封裝物件,使 CallHandler 生效。

2. 建立 PolicyInjectionExtension

public class PolicyInjectionExtension : UnityContainerExtension
{
    protected override void Initialize()
    {
        base.Context.Strategies.AddNew<PolicyInjectionStrategy>(UnityBuildStage.Initialization);
    }
}

3. 程式碼方式套用

[CachingCallHandler]
public class TimeService : ITimeService
{
    public DateTime GetSystemTime() => DateTime.Now;
}

IUnityContainer container = new UnityContainer();
container.AddExtension(new PolicyInjectionExtension());
container.RegisterType<ITimeService, TimeService>();
var instance = container.Resolve<ITimeService>();
for (int i = 0; i < 10; i++)
{
    Console.WriteLine(instance.GetSystemTime());
    Thread.Sleep(1000);
}

輸出時間相同,證明快取生效。輸出結果

4. 配置方式套用

<unity>
  <containers>
    <container>
      <types>
        <type type="Artech.PolicyInjectionIntegratedInUnity.ITimeService, Artech.PolicyInjectionIntegratedInUnity" mapTo="Artech.PolicyInjectionIntegratedInUnity.TimeService, Artech.PolicyInjectionIntegratedInUnity" />
      </types>
      <extensions>
        <add type="Artech.PolicyInjectionIntegratedInUnity.PolicyInjectionExtension, Artech.PolicyInjectionIntegratedInUnity" />
      </extensions>
    </container>
  </containers>
</unity>

程式碼改為讀取配置:

IUnityContainer container = new UnityContainer();
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(container);
var instance = container.Resolve<ITimeService>();
// ...

同樣獲得相同輸出。配置方式輸出

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

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