中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

基礎才(cai)是重中之重~泛型類的(de)靜態構造方法(fa)可不(bu)是只執行一次呀

回到目錄

最近做了一個數據庫的讀寫分離項目,使用到了DbCommand攔(lan)截器,在程序開發過程中沒有發現(xian)什么特別的(de)(de)問(wen)題(ti)(ti),而當(dang)開發完成后,在進行(xing)測試階段時(shi),一(yi)個(ge)(ge)偶然(ran)的(de)(de)機會讓我發現(xian)了,原來我的(de)(de)攔(lan)截器注入(ru)不(bu)只是注入(ru)一(yi)次,而是每種類型的(de)(de)倉儲都會注入(ru)一(yi)次,這(zhe)個(ge)(ge)問(wen)題(ti)(ti)事實(shi)上是相關嚴(yan)重(zhong)的(de)(de)一(yi)件事,如果你的(de)(de)攔(lan)截器處理邏輯很(hen)多,那么,這(zhe)將(jiang)是非常消耗性(xing)能(neng)的(de)(de)。

原(yuan)因,靜態(tai)構造方法對(dui)泛(fan)型類不(bu)是唯一的(de),而是相互獨立(li)的(de)

  public abstract class DbContextRepository<TEntity> :
         ISpecificationRepository<TEntity>
          where TEntity : class
    {
        #region Constructors

        /// <summary>
        /// 靜態構造(zao)方(fang)法對每(mei)個TEntity是獨(du)立的,有多(duo)少類型初始化(hua),這(zhe)個方(fang)法就執行多(duo)少次
        /// </summary>
        static DbContextRepository()
        {
         //泛型類的靜態構造方(fang)法...
        }
 }

結果,每個(ge)類(lei)型初始化時,都會(hui)向攔截器(qi)字典(dian)中添(tian)加一條

   IRepository<WebManageUsers> userWrite = new BackgroundRepositoryBase<WebManageUsers>(db);
   IRepository<WebManageMenus> menuWrite = new BackgroundRepositoryBase<WebManageMenus>(db);
  //每次(ci)初始化,靜態構造(zao)方法都會被執(zhi)行

事實上,這是可以理解的,因為泛型類本身就是未定義的,當你初始化它時,具體的類型才被運行時得知,這時,在第一次使用它時,“這個類”的靜態構造方法才會被執行,這是完全沒問題的,可能開發人員有時就忽略了這一點。

解決,使(shi)用反(fan)射來實現(xian)自(zi)己的按需添加(jia)

    /// <summary>
    /// DbCommand攔截器擴展
    /// </summary>
    public static class DbCommandInterceptorExtensions
    {
        /// <summary>
        /// 將DbCommand的(de)攔(lan)截器以單例的(de)形式添加到DbInterception靜(jing)態對象中
        /// </summary>
        /// <param name="action"></param>
        public static void UsingSingletonInterceptor(DbCommandInterceptor interceptor)
        {
            #region SQL語句攔截器,攔截器只加載一次
            var property = typeof(DbCommandDispatcher).GetProperty("InternalDispatcher", BindingFlags.Instance | BindingFlags.NonPublic);
            if (property != null)
            {
                var val = property.GetValue(System.Data.Entity.Infrastructure.Interception.DbInterception.Dispatch.Command);
                if (val != null)
                {
                    var list = val.GetType().GetField("_interceptors", BindingFlags.Instance | BindingFlags.NonPublic);
                    if (list != null)
                    {
                        var listVal = list.GetValue(val) as List<System.Data.Entity.Infrastructure.Interception.IDbCommandInterceptor>;
                        if (listVal != null)
                        {
                            if (listVal.FirstOrDefault(i => i.ToString() == interceptor.GetType().ToString()) == null)
                            {
                                System.Data.Entity.Infrastructure.Interception.DbInterception.Add(interceptor);
                            }
                        }
                    }
                }
            }
            #endregion
        }
    }

調用這很方便

  EntityFrameworks.Data.Core.Extensions.DbCommandInterceptorExtensions.UsingSingletonInterceptor(new CommandInterceptor());

OK,這樣我們的每個攔截器在DbInterception對象中都只會出現一次,再也不會出現一個攔截器被(bei)執行多次的情況(kuang)了,呵(he)呵(he)。

回到目錄

posted @ 2015-01-14 11:14  張占嶺  閱讀(2252)  評論(0)    收藏  舉報