熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

.NET面向上下文、AOP架構模式

2022-06-13   來源: .NET編程 

  上下文Context面向切面編程AOP模型分析
   
    在本人的NET面向上下文AOP架構模式(概述)一文中我們大概了解了上下文如何輔助對象在運行時的管理在很多時候我們急需在運行時能把對象控制在一定的邏輯范圍內在必要的時候能讓他們體現出集中化的概念如人群車輛動物等等而Context與AOP有著密切的聯系Context表示邏輯抽象的范圍而AOP描述了在這個邏輯范圍內如何進行控制其實這兩者都是設計模式外的設計模式與具體的技術實現無關[王清培版權所有轉載請給出署名]
   
    那麼Context與AOP兩者在邏輯上是一個怎樣的概念呢?似乎只有圖才能最貼切的表達人的理解思路下圖展現Context與AOP緊密合作的概念模型
   
    Context圖

   

  對象在運行時被上下文管理在上下文中可以很方便的獲取到所有的受管理的對象這為後面的AOP做了鋪墊只有Context啟動後AOP管理器的爪子才能伸進對象的運行時內部與AOP的連接點建立起通訊關系才能真正的使對象能面向切面成功


   
    在模型圖中Context中心負責對所有Object進行管理而Object體現出多面性屬性多面性行為都將包括多面性的特點通過與AOP管理器進行連接將控制對象的運行時行為
   
    AOP圖

   

  通過合理的約定對象的AOP抽象接口盡可能的最大化將控制權移動到客戶所實現的中去比如對某類方法的調用可能需要盡可能的控制方法的所有執行權所以對具體的抽象定義有很大的難度
   
    在上圖中我們通過AOP核心管理器與對象的連接上根據具體的類型進行動態調用比如屬性可能需要在運行時根據業務環節進行呈現動態綁定等等都可以通過AOP去實現對於方法可能在面向SOA的架構中需要記錄下當前客戶端的調用信息還有一些獨特的業務認證等等不同的需要進行邏輯抽象這也符合面向對象的設計原則很多時候我們需要先約定而不是盡可能的提供擴展的機制擴展點越多系統的復雜程度就越大相對也就難以控制
   
    上下文的實現
   
    對上下文AOP模型我們大致分析了一下通過模型圖也很形象的體現出上下文AOP的主要的工作原理下面我們來通過具體的分析來搭建物理的代碼模型
   
    面向對象是對抽象的邏輯模型進行物理性的建模能否真正的體現出模型需要我們細心的分析才行
   


    上下文模型實現
   
    我們對上下文模型進行抽象實現為代碼模型那麼我們需要一個邏輯上代表上下文的對象在這裡我將它命名為ContextRuntime上下文的生命周期控制在Using()語句的代碼段中那麼ContextRuntime需要實現Idisposable接口讓Using()語句能起作用
   
    using (ContextModuleContextRuntimeBeginContextRuntime())
   
    {   //上下文的生命周期
   
    }
   
    為什麼要這樣設計上下文的生命周期呢這樣設計是最為靈活的在諸如很多微軟的內部上下文生命周期的入口也是這樣設計的最經典的就是SystemTransaction事務處理
   
    當Using()代碼段結束後我們需要釋放當前上下文實例所以我們需要完成IDisposable接口的實現
   
    void IDisposableDispose()
   
    {
   
    _currentContextRuntime = null;
   
    }
   
    _ currentContextRuntime表示上下文對象實例的全局私有對象
   
    由於多線程應用框架的入口點不是我們所能控制的所以在使用上下文模式的時候需要使用線程本地存儲解決線程不安全訪問的問題
   
    [ThreadStatic]
   
    private static ContextRuntime _currentContextRuntime;
   
    我們看一下全部的ContextRuntime對象代碼
   
    [csharp]
   
    /***
   
    * author:深度訓練
   
    * blog:
   
    * **/
   
    using System;
   
    using SystemCollectionsGeneric;
   
    using SystemText;
   
    namespace ContextModule
   
    {
   
    /// <summary>
   
    /// 上下文運行時環境
   
    /// 上下文邏輯運行時環境環境中的功能都是可以通過附加進來的
   
    /// </summary>
   
    public class ContextRuntime : IDisposable
   
    {
   
    #region IDisposable成員
   
    void IDisposableDispose()
   
    {
   
    _currentContextRuntime = null;
   
    }
   
    #endregion
   
    protected ContextRuntime() { }
   
    private DateTime _initTime = DateTimeNow;
   
    /// <summary>
   
    /// 獲取運行時創建上下文的時間
   
    /// </summary>
   
    public virtual DateTime InitTime { get { return _initTime; } }
   
    private Dictionary<object object> _runTimeResource = new Dictionary<object object>()
   
    private ContextFilterHandlerMap _filterMap = new ContextFilterHandlerMap()
   
    /// <summary>
   
    /// 獲取上下文中的方法類過濾器映射表
   
    /// </summary>
   
    public ContextFilterHandlerMap FilterMap { get { return _filterMap; } }
   
    private Guid _initPrimaryKey = GuidNewGuid()
   
    /// <summary>
   
    /// 獲取運行時創建上下文的唯一標識
   
    /// </summary>
   
    public virtual Guid InitPrimaryKey { get { return _initPrimaryKey; } }
   
    /// <summary>
   
    /// 獲取上下文共享區域中的數據
   
    /// </summary>
   
    /// <param name=key>數據Key</param>
   
    /// <returns>object數據對象</returns>
   
    public virtual object GetValue(object key)
   
    {
   
    return _runTimeResource[key];
   
    }
   
    /// <summary>
   
    /// 設置上下文共享區域中的數據
   
    /// </summary>
   
    /// <param name=key>數據Key</param>
   
    /// <param name=value>要設置的數據對象</param>
   
    public virtual void SetValue(object key object value)
   
    {
   
    _runTimeResource[key] = value;
   
    }
   
    [ThreadStatic]
   
    private static ContextRuntime _currentContextRuntime;
   
    /// <summary>
   
    /// 獲取當前上下文運行時對象
   
    /// </summary>
   
    public static ContextRuntime CurrentContextRuntime { get { return _currentContextRuntime; } }
   
    /// <summary>
   
    /// 開始運行時上下文
   
    /// </summary>
   
    /// <returns>ContextRuntime</returns>
   
    public static ContextRuntime BeginContextRuntime()
   
    {
   
    //可以通過配置文件配置上下文運行時環境的參數這裡只是實現簡單的模擬
   
    _currentContextRuntime = new ContextRuntime()
   
    return _currentContextRuntime;
   
    }
   
    }
   
    }
   
    這裡只為了實現基本的模型原型不會涉及太多的功能上下文主要是在當前線程中開啟然後保持在靜態對象的多線程安全訪問最後就是對象的穩定釋放
   
    上下文對象綁定實現
   
    有了上下文之後如何才能使對象在運行時動態的綁定到上下文中來這個需要在前期編碼的時候就確定對象是否要綁定到當前上下文以便進行管理
   
    那麼我們需要對客戶使用的對象進行一個抽象讓所有需要綁定的對象實現我們高層定義的抽象這裡我將命名為ContextModuleBaseObject由於需要向AOP提供對象的的連接點所以我們需要在運行時反射獲取到綁定對象的一些基本信息屬性的行為的包括對象本身的這些面我們需要將其對應關系建立起來才能讓後面的AOP起作用
   
    所以我們將ContextModuleBaseObject定義為泛型類並且需要加上Class的約束對於綁定的對象在運行時一旦進入上下文的生命周期管理就需要靈活的表示為ContextRuntime對象這樣設計符合上下文一視同仁的觀念更便於ContextModuleBaseObject對象在運行期動態的使用上下文的內部存儲區域[王清培版權所有轉載請給出署名]


   
    這裡我們需要將ContextModuleBaseObject 對象繼承自ContextRuntime對象使用經典的裝飾者模式讓ContextModuleBaseObject 對象使用ContextRuntime 行為
   
    [csharp]
   
    /***
   
    * author:深度訓練
   
    * blog:
   
    * **/
   
    using System;
   
    using SystemCollectionsGeneric;
   
    using SystemText;
   
    using SystemReflection;
   
    namespace ContextModule
   
    {
   
    /// <summary>
   
    /// 上下綁定基類強制派生類綁定到上下文
   
    /// 邏輯上下文的策略構造都在這裡進行
   
    /// </summary>
   
    /// <typeparam name=T>受管理的上下文綁定對象類型通常是ContextModuleBaseObject派生類</typeparam>
   
    public class ContextModuleBaseObject<T> : ContextRuntime where T : class
   
    {
   
    /// <summary>
   
    /// 當前上下文綁定對象所綁定到的上下文物理對象實例
   
    /// </summary>
   
    private ContextRuntime _contextRunTime;
   
    public ContextModuleBaseObject()
   
    {
   
    if (typeof(T)GetCustomAttributes(typeof(ContextEveningBoundAttribute) false) != null)
   
    {
   
    _IsEvening = true;
   
    return;
   
    }
   
    //前期靜態綁定上下文
   
    if (ContextRuntimeCurrentContextRuntime == null)
   
    throw new Exception(上下文環境未能初始化請檢查您的代碼入口是否啟用了ContextRuntime對象
   
    _contextRunTime = ContextRuntimeCurrentContextRuntime;
   
    _InitContextHandler<T>()
   
    }
   
    /// <summary>
   
    /// 構造上下文的類過濾器方法過濾器映射表
   
    /// </summary>
   
    private void _InitContextHandler<ChildType>() where ChildType : class
   
    {
   
    //構造類過濾器
   
    ContextOperationBaseAttribute[] classattr =
   
    typeof(ChildType)GetCustomAttributes(typeof(ContextOperationBaseAttribute) false) as ContextOperationBaseAttribute[];
   
    if (classattrLength >
   
    {
   
    ContextOperationBaseAttribute joinoper = _JoinOperation(classattr)
   
    _contextRunTimeFilterMapMapOperation(typeof(T)FullName joinoper)
   
    }
   
    //構造方法過濾器
   
    foreach (MethodInfo method in typeof(ChildType)GetMethods())
   
    {
   
    ContextOperationBaseAttribute[] methodattr =
   
    methodGetCustomAttributes(typeof(ContextOperationBaseAttribute) false) as ContextOperationBaseAttribute[];
   
    if (methodattrLength <=
   
    continue;
   
    ContextOperationBaseAttribute joinoper = _JoinOperation(methodattr)
   
    _contextRunTimeFilterMapMapOperation(stringFormat({}{} methodDeclaringTypeFullName methodName) joinoper)
   
    }
   
    }
   
    internal bool _IsEvening { get; set; }
   
    /// <summary>
   
    /// 後期動態綁定上下文
   
    /// </summary>
   
    internal void _EveningBoundChildClass<ChildType>() where ChildType : class
   
    {
   
    if (_contextRunTime != null)
   
    return;//說明之前已經進行過動態調用
   
    _contextRunTime = ContextRuntimeCurrentContextRuntime;//動態綁定當前運行時上下文
   
    _InitContextHandler<ChildType>()
   
    }
   
    private ContextOperationBaseAttribute _JoinOperation(ContextOperationBaseAttribute[] operationarray)
   
    {
   
    //必須對數組進行排序後才能連接
   
    for (int i = ; i < operationarrayLength; i++)
   
    {
   
    for (int j = ; j < i; j++)
   
    {
   
    if (operationarray[j]OperationSort > operationarray[j + ]OperationSort)
   
    {
   
    ContextOperationBaseAttribute oper = operationarray[j];
   
    operationarray[j] = operationarray[j + ];
   
    operationarray[j + ] = oper;
   
    }
   
    }
   
    }
   
    ContextOperationBaseAttribute opernext = operationarray[];
   
    for (int i = ; i < operationarrayLength; i++)
   
    {
   
    opernextNextOperation = operationarray[i];
   
    opernext = operationarray[i];//保持對當前循環對象的上級對象的引用
   
    }
   
    return operationarray[];
   
    }
   
    public MethodInfo GetMethodInfo(string methodname)
   
    {
   
    return thisGetType()GetMethod(methodname)
   
    }
   
    public override Guid InitPrimaryKey
   
    {
   
    get
   
    {
   
    return _contextRunTimeInitPrimaryKey;
   
    }
   
    }
   
    public override DateTime InitTime
   
    {
   
    get
   
    {
   
    return _contextRunTimeInitTime;
   
    }
   
    }
   
    public override object GetValue(object key)
   
    {
   
    return _contextRunTimeGetValue(key)
   
    }
   
    public override void SetValue(object key object value)
   
    {
   
    _contextRunTimeSetValue(key value)
   
    }
   
    }
   
    }
   
    ContextModuleBaseObject 類主要實現的功能就是將對象動態的添加到當前上下文中然後為AOP做些輔助性的工作包括對類屬性行為的特性元數據的緩存這裡只實現了行為的特性緩存可以根據自己的需要擴展AOP的功能在對象的屬性上標記特性讓屬性也發揮作用這裡的特性就是AOP公布的指定接口

   
    對_JoinOperation方法的解釋我們留在後面這裡是一個數據結構將ContextOperationBaseAttribute
   
    類型串成鏈表讓方法的執行穿過所有的ContextOperationBaseAttribute處理類
   
    上下文對象的後期綁定實現
   
    為了讓綁定對象支持上下文後期綁定需要一個特性作為表示
   
    [csharp]
   
    /***
   
    * author:深度訓練
   
    * blog:
   
    * **/
   
    using System;
   
    using SystemCollectionsGeneric;
   
    using SystemText;
   
    namespace ContextModule
   
    {
   
    /// <summary>
   
    /// 確定設置類是否需要後期動態綁定到上下文
   
    /// 使用該特性的類將是上下文活躍的只有在使用的時候才確定當前上下文
   
    /// </summary>
   
    [AttributeUsage(AttributeTargetsClass AllowMultiple = false Inherited = true)]
   
    public class ContextEveningBoundAttribute : Attribute
   
    {
   
    public ContextEveningBoundAttribute() { }
   
    private bool _isEvening;
   
    /// <summary>
   
    /// 指定對象是否需要後期動態綁定上下文
   
    /// </summary>
   
    public bool IsEvening { set { _isEvening = value; } get { return _isEvening; } }
   
    }
   
    }
   
    僅僅為了標識後期綁定說明在ContextModuleBaseObject 對象的構造函數中可以看到
   
    [csharp]
   
    public ContextModuleBaseObject()
   
    {
   
    if (typeof(T)GetCustomAttributes(typeof(ContextEveningBoundAttribute) false) != null)
   
    {
   
    _IsEvening = true;
   
    return;
   
    }
   
    //前期靜態綁定上下文
   
    if (ContextRuntimeCurrentContextRuntime == null)
   
    throw new Exception(上下文環境未能初始化請檢查您的代碼入口是否啟用了ContextRuntime對象
   
    _contextRunTime = ContextRuntimeCurrentContextRuntime;
   
    _InitContextHandler<T>()
   
    }
   
    到這裡我們已經實現對象的動態綁定到上下文來下面我們來分析Context如何用AOP配合完成面向切面編程的機制
   
    AOP中的對象行為的契約設計實現
   
    其實這裡的契約設計也就是圖中對AOP中的的約定
   
    AOP全稱為面向切面編程對象在運行時具備多個面其實在NET裡面我們習慣性的用特性(Attribute)來表達這個概念因為不需要改動任何代碼就可以將特性加到對象中的任何元素中去在不同的業務環節或者說是功能環節就能動態的轉動元素體現出切面的優勢當然具體的實現可能很多種這裡使用特性來完成


   
    在此約定任何處理對象方法的都將被抽象這裡我將命名為ContextOperationBaseAttribute該特性表示所有附加到方法上的特性的基類的抽象
   
    那麼不同類型的面將有著不同的操作行為比如記錄日志的特性計算性能的特性認證安全的特性他們都有著不同的行為和屬性所以這裡我們還需要提取一個頂層接口作為行為類的特性處理抽象這裡我將命名為IContextOperationHandler該接口作為統一執行行為特性的高層依賴其實這裡也體現出依賴倒置原則依賴抽象不依賴具體實現
   
    完整的ContextOperationBaseAttribute 類
   
    [csharp]
   
    /***
   
    * author:深度訓練
   
    * blog:
   
    * **/
   
    using System;
   
    using SystemCollectionsGeneric;
   
    using SystemText;
   
    namespace ContextModule
   
    {
   
    /// <summary>
   
    /// 上下文操作動作特性化基類
   
    /// 所有對上下文中的類方法的過濾操作都必須繼承此類
   
    /// </summary>
   
    public abstract class ContextOperationBaseAttribute : Attribute IContextOperationHandler
   
    {
   
    /// <summary>
   
    /// 過濾器的處理順序從小到大的方式進行處理
   
    /// </summary>
   
    public int OperationSort { get; set; }
   
    /// <summary>
   
    /// 下一次過濾操作類
   
    /// </summary>
   
    internal ContextOperationBaseAttribute NextOperation { get; set; }
   
    /// <summary>
   
    /// 開始處理過濾對象
   
    /// </summary>
   
    /// <typeparam name=Result>方法的返回值類型</typeparam>
   
    /// <param name=actionmethod>調用的方法包裝</param>
   
    /// <param name=paramarray>方法的有序參數</param>
   
    /// <returns></returns>
   
    public virtual Result ResultAction<Result>(ContextMethodInfo actionmethod params object[] paramarray)
   
    {
   
    object result = null;
   
    if (!actionmethodIsPost)
   
    {
   
    result = (this as IContextOperationHandler)Operation(actionmethod paramarray)
   
    if (thisNextOperation != null)
   
    return thisNextOperationResultAction<Result>(actionmethod paramarray)
   
    }
   
    if (result != null)
   
    return (Result)result;
   
    return default(Result)
   
    }
   
    public abstract object Operation(ContextMethodInfo contextmethod params object[] paramarray)
   
    }
   
    }
   
    作為抽象的頂層類需要完成派生類重復的勞動這裡實現了一個ResultAction泛型方法該方法是外部調用綁定對象的方法時的入口點但是具體的實現區別在於IContextOperationHandler 接口的定義
   
    由於行為的特性可能存在多個所以對於最後一個處理完的特性需要結束整個的調用鏈表並且返回值在ResultAction虛方法裡面對IContextOperationHandler 接口的Operation方法執行調用該方法將會在實現特定行為特性裡面實現這裡又體現出模板方法設計模式在抽象類中約定行為在派生類中實現具體
   
    這裡比較有意思的是特性不在像大家實現ORM的那中簡單的標識了其實特性真正強大的地方在於運行時能動態的獲取到這得益於NET元數據的功勞並且動態實例化然後當作普通的對象實例使用這個觀念很多NET程序員不宜轉變
   
    在這裡的ContextOperationBaseAttribute 又描述了另外一種數據結構單向鏈表為了將綁定對象的行為最大化的在特性中實現我們將方法的調用完全的傳遞到實現特性中去那麼對方法上多個作用的特性如何穿過呢並且能保證數據的正常傳遞和返回有兩點我們需要注意一個是特性的作用順序二個是特性對方法的執行是否完成這兩點我們都要考慮進去所以在ContextOperationBaseAttribute 類中用public int OperationSort { get; set; }屬性表示特性的執行順序記錄日志的特性和計算性能的特性我們很難在這裡定死需要根據後期程序的執行情況而定如我要先記錄日志然後在執行方法
   
    那麼我們又如何將ContextOperationBaseAttribute類型串聯起來呢?在ContextModuleBaseObject
   
    泛型綁定類中我們在構造的時候就將通過ContextOperationBaseAttribute OperationSort 屬性初始化了特性處理鏈表
   
    那麼我們如何將具體的對象與特性關聯建立起對應關系呢?一個行為可能有多個ContextOperationBaseAttribute的實現所以這裡我們需要一個能滿足行為與特性之間的數據結構
   
    這裡我將它定義為ContextFilterHandlerMap該類繼承自Dictionary<stringContextOperationBaseAttribute>泛型字典類使用KEYVALUE的方式存放行為與ContextOperationBaseAttribute處理特性的對應關系
   
    [csharp]
   
    /***
   
    * author:深度訓練
   
    * blog:
   
    * **/
   
    using System;
   
    using SystemCollectionsGeneric;
   
    using SystemText;
   
    namespace ContextModule
   
    {
   
    /// <summary>
   
    /// 特定於上下文的過濾器映射表
   
    /// 上下文中的任何方法如果需要進行上下文管理的則使用ContextModuleContextOperationBaseAttribute特性派生類進行管理


    
    /// 所有附加於方法類上的特性管理類都將被映射到ContextModuleContextFilterHandlerMap實例中
   
    /// </summary>
   
    public class ContextFilterHandlerMap : Dictionary<string ContextOperationBaseAttribute>
   
    {
   
    public ContextFilterHandlerMap() { }
   
    /// <summary>
   
    /// 獲取方法對應的過濾器處理特性
   
    /// </summary>
   
    /// <param name=mapname>映射Key</param>
   
    /// <returns>ContextOperationBaseAttribute特性實例</returns>
   
    public ContextOperationBaseAttribute MapOperation(string mapname)
   
    {
   
    return this[mapname];
   
    }
   
    /// <summary>
   
    /// 設置過濾器與特定方法的映射
   
    /// </summary>
   
    /// <param name=mapname>映射Key</param>
   
    /// <param name=operationlist>過濾器特性基類ContextOperationBaseAttribute</param>
   
    public void MapOperation(string mapname ContextOperationBaseAttribute operationlist)
   
    {
   
    thisAdd(mapname operationlist)
   
    }
   
    }
   
    }
   
    最後只需要向外提供IContextOperationHandler 接口就可以實現方法與處理特性的串聯了
   
    [csharp]
   
    /***
   
    * author:深度訓練
   
    * blog:
   
    * **/
   
    using System;
   
    using SystemCollectionsGeneric;
   
    using SystemText;
   
    using SystemIO;
   
    namespace ContextModule
   
    {
   
    /// <summary>
   
    /// 上下文操作管理接口
   
    /// </summary>
   
    public interface IContextOperationHandler
   
    {
   
    /// <summary>
   
    /// 開始上下文處理
   
    /// </summary>
   
    /// <param name=contextmethod>CRL目前正在執行的上下文方法的信息
   
    /// 可以通過ContextMethodInfo實例獲取方法詳細信息</param>
   
    ///<param name=paramarray>參數數組</param>
   
    object Operation(ContextMethodInfo contextmethod params object[] paramarray)
   
    }
   
    }
   
    通過對外公開接口讓實現的客戶端去完成對具體對象方法的執行ContextMethodInfo 類型是包裝SystemReflection MethodInfo方法元數據的將通過調用切入到方法內部
   
    這裡基本上實現了AOP對行為的多面支持下面我們來看一下如果動態的切入到方法中
   
    動態入口的實現
   
    對所有方法的調用將是比較頭疼的由於一般面向上下文面向切面都是有編寫者控制對方法的調用可以很方便的通過後台的隱式的調用但是作為普通的方法的入口調用主要有三種方式實現
   
    委托實現入口
   
    通過使用SystemDelegate動態派生類型來完成對方法的調用但是委托對於方法的簽名必須是強類型的所以很難做到通用的調用入口
   
    反射實現入口(通過擴展方法在OBJECT基類中加入獲取MethodInfo對象的方法使用時通過該方法獲取調用方法的信息)
   
    通過擴展方法在SystemObject中加入一個擴展方法用來獲取調用方法的信息然後通過反射動態的調用這種方法只比較常用的但是如何框架是在NET中使用的擴展方法還不能實現這裡我是在ContextModuleBaseObject基類中加了一個類似擴展方法的方式綁定對象可以很方便的獲取到調用方法的MethodInfo對象


   
    完美的動態編譯(向抽象多態敬禮)
   
    最為完美的是擴展代碼生成提供程序在使用的對象裡面在派生一個類專門用來進行多態的轉移讓高層的調用順利進入到派生的類中不過比較復雜
   
    這裡是使用第二種方式使用的
   
    [csharp]
   
    /***
   
    * author:深度訓練
   
    * blog:
   
    * **/
   
    using System;
   
    using SystemCollectionsGeneric;
   
    using SystemText;
   
    using SystemReflection;
   
    namespace ContextModule
   
    {
   
    /// <summary>
   
    /// 面向上下文的操作類
   
    /// 對上下文發起的方法調用需要通過該基類進行調用才能讓我們的擴展點使用成為可能
   
    /// </summary>
   
    public static class ContextAction
   
    {
   
    /// <summary>
   
    /// 在面向上下文的環境中進行方法的調用
   
    /// </summary>
   
    /// <typeparam name=PostObjectType>調用的上下文綁定對象類型</typeparam>
   
    /// <typeparam name=ResultType>方法的返回類型</typeparam>
   
    /// <param name=post>調用的上下文綁定對象的實例</param>
   
    /// <param name=method>方法的信息對象MethodInfo通過OjectGetContextMethodInfo方法自動獲取</param>
   
    /// <param name=paramarray>方法的有序參數集合</param>
   
    /// <returns>ResultType泛型類型指定的返回實例</returns>
   
    public static ResultType PostMethod<PostObjectType ResultType>(PostObjectType post MethodInfo method params object[] paramarray)
   
    where PostObjectType : ContextModuleBaseObject<PostObjectType>
   
    {
   
    _LockPostObejctIsEveningBound<PostObjectType>(post)
   
    string key = stringFormat({}{} methodDeclaringTypeFullName methodName)
   
    if (!ContextRuntimeCurrentContextRuntimeFilterMapContainsKey(key))
   
    {
   
    throw new Exception(stringFormat(方法{}未經過上下文進行管理 key))
   
    }
   
    ContextMethodInfo contextmethod = new ContextMethodInfo(method post)
   
    return ContextRuntimeCurrentContextRuntimeFilterMap[key]ResultAction<ResultType>(contextmethod paramarray)
   
    }
   
    /// <summary>
   
    /// 檢查調用實例類是否屬於後期綁定
   
    /// 通過使用ContextModuleContextEveningBound(IsEvening = true)方式指定後期綁定上下文
   
    /// </summary>
   
    private static void _LockPostObejctIsEveningBound<PostObjectType>(PostObjectType post)
   
    where PostObjectType : ContextModuleBaseObject<PostObjectType>
   
    {
   
    ContextModuleBaseObject<PostObjectType> contextclass = post as ContextModuleBaseObject<PostObjectType>;
   
    if (contextclass_IsEvening)
   
    contextclass_EveningBoundChildClass<PostObjectType>()
   
    }
   
    }
   
    }
   
    所有的調用均使用PostMethod泛型方法啟動_LockPostObejctIsEveningBound私有方法判斷當前類型是否是後期綁定如果是則需要切入到基類中調用_ EveningBoundChildClass方法進行ContextOperationBaseAttribute 類型的鏈表構造然後直接通過頭對象進行調用
   
實例上下文與靜態上下文
   
    對於實例上下文同時也就存在靜態上下文的概念對於靜態對象的邏輯歸納有點難度由於靜態對象在面向對象設計方面很難抽象只能通過特性注入的方式強制性的將靜態對象拉入上下文但是在多線程的情況下確實是可以研究的將靜態對象全部進行線程本地存儲強制性的進行類似實體對象的管理
   
 面向上下文的領域模型(DMM)
   
    基於上下文的使用模式可以進行領域模型的初步構造可以先向領域中的大比例結構靠近將業務模型邏輯歸納到一定的Context中對業務的模塊化梳理也是一種實現[王清培版權所有轉載請給出署名]
   
    在分層架構中的業務邏輯層可能需要加入上下文的管理將業務模型進行運行時控制比如訂單處理將訂單業務流程相關的模型對象歸納為一塊比如用戶相關將用戶管理的業務流程相關的模型對象歸納為一塊確實是很有意思


From:http://tw.wingwit.com/Article/program/net/201311/11723.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.