ASP.NET MVC系列 框架搭建(二)之倉儲層的優化


大神勿噴,小神默默學。

會了就是不值一提的東西,不會就是絕對的高大上。

最后上傳源碼。希望能給讀者帶來一些新的認識及知識。

還沒上過頭條。。各位大神,請點支持一下小弟。

陸續更新。更新到你會為止!!

我不是話嘮,我只把重點點出來,細枝末節的不懂的可以留言探討。這個系列的最后,我會再統一的把大家的問題,列在一篇新的Blog。工作需要規划,寫博客也是如此。

需求

①請保持EF上下文的線程唯一。防止臟臨時數據的出現

②請對程序擴展性做好設計。以后ef框架可能改為Spring框架

③服務層調用倉儲層時。DBContext為統一入口

    ③.1 方便程序員開發,提供統一入口。把ef封裝到此入口里面。

    ③.2防止臟臨時數據的出現,“也”請保持這個入口的線程內唯一。

    ③.3要這個統一入口去除服務層和倉儲層的耦合

思路

①把ef放進CallContext內。鍵值對形式存放。

②面向接口的思想

 新建一個工廠接口+工廠。用一個“工廠方法”模式,非“簡單工廠”,也非“抽象工廠”設計模式。如果您對工廠的幾個設計模式不了解,請參考我寫過的設計模式一篇blog。

③ ③.1新建一個類,命名DBContact里面的一個屬性類型為ObjectContext,因為上下文繼承ObjectContext,繼而“點”多個倉儲。 

    ③.2放進CallContext內。鍵值對存儲。

    ③.3新建一個IDBContact接口,讓DBContact繼承。用一個工廠繼承一個接口工廠創建。“工廠方法”設計模式

思想

面向接口+工廠模式+線程唯一 2個抽象方法工廠作用:線程唯一+擴展性(面向接口)

 

詳情代碼

ISingleEFCntextFactory.cs

 

using System.Data.Objects;

namespace LKBS.CommunicationPlatform.IDAL
{
 public interface ISingleEFCntextFactory
 {//no public
 ObjectContext GetCurrentEFContext();
 }
}

 

SingleEFCntextFactory.cs

using LKBS.CommunicationPlatform.IDAL;
using System.Data.Objects;//添加引用 System.Data.Entity
using System.Runtime.Remoting.Messaging;
using LKBS.CommunicationPlatform.Model;


namespace LKBS.CommunicationPlatform.Factory
{
 public class SingleEFCntextFactory : ISingleEFCntextFactory
 {
  public ObjectContext GetCurrentEFContext()
  {
   //把上下文(基類)放在一個線程內。讓一次請求(一個ACTION)可能執行CRUD中的幾步,公用一個上下文.
   ObjectContext callEFContext = (ObjectContext)CallContext.GetData("efContext");//線程槽 存放“鍵值對”
   //先讀后寫。沒有就new一個上下文
   if (callEFContext == null)
   {
    callEFContext = new ModelContainer();
   }
   CallContext.SetData("efContext", callEFContext);
   return callEFContext;
  }
 }
}

BaseRespository.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data.Entity;
using LKBS.CommunicationPlatform.Model;
using LKBS.CommunicationPlatform.IDAL;
using System.Data;
using LKBS.CommunicationPlatform.Factory;
using System.Data.Objects;


namespace LKBS.CommunicationPlatform.DAL
{
   public class BaseRespository<T> where T : class,new()
   {
      ISingleEFCntextFactory singleEFFactory = new SingleEFCntextFactory();
      //中間加一個工廠,這里“去除”ef和具體倉儲的耦合。可以更換ef。而Respositiry db不用變
      ObjectContext db;//如果沒賦值,那就是賦值的問題。找對應賦值的工廠 或者工廠還沒編譯
      public BaseRespository()
      {
         ObjectContext db = singleEFFactory.GetCurrentEFContext();
      }

      //ModelContainer db = efFactory.GetCurrentEFContext();
      //字段初始值無法引用非靜態字段、方法或屬性.
      //那我們在構造方法內賦值
....CRUD
    }
}

為方便業務邏輯層調用,建立統一入口。

IDBContact.cs

using System.Data.Objects;//上下文在的空間

namespace LKBS.CommunicationPlatform.IDAL
{
  public interface IDBContact
   {
    //接口中的屬性要{}
    ObjectContext currentEFContext { get; set; }
    IUserInforRespository userinforResponsity { get; set; }
    //...多個其他表的倉儲,在T4模板中加OK
   }
}

DBContact.cs

using LKBS.CommunicationPlatform.IDAL;
using System.Data.Objects;//上下文的命名空間
using LKBS.CommunicationPlatform.Factory;

namespace LKBS.CommunicationPlatform.DAL
{
 public class DBContact : IDBContact
 {
  public ObjectContext currentEFContext { get; set; }
  ISingleEFCntextFactory singleEFCntextFactory = new SingleEFCntextFactory();//SingleEFCntextFactory做到單一上下文
  public DBContact()
  {
   currentEFContext = singleEFCntextFactory.GetCurrentEFContext();//
  }
  public IUserInforRespository userinforResponsity { get; set; }
 }
}

ISingleDBContactFactory.cs

namespace LKBS.CommunicationPlatform.IDAL
{
  public interface ISingleDBContactFactory
   {
      IDBContact CreateDBCotactUseEF();
   }
}

SingleDBContactFactory.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using LKBS.CommunicationPlatform.IDAL;
using System.Data.Objects;
using System.Runtime.Remoting.Messaging;
using LKBS.CommunicationPlatform.DAL;


namespace LKBS.CommunicationPlatform.Factory
{
   //繼承接口①接口要編譯過,②引入接口所用的程序集+ using
   class SingleDBContactFactory : ISingleDBContactFactory
   {
      public IDBContact CreateDBCotactUseEF()
      {
         //ObjectContext currentEFContext = new ObjectContext("currentEFContext");
         //return currentEFContext;
         IDBContact dbCotact = (DBContact)CallContext.GetData("currentDBContact");
         if (dbCotact==null)
         {
            dbCotact = new DBContact();
         }
         CallContext.SetData("currentDBContact", dbCotact);
         return dbCotact;

      }
   }
}

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM