ASP.NET MVC系列 框架搭建(三)之服務層的搭建


邯鄲學步

吾雖是一不知名的菜鳥,但,吾亦有一個從后台程序員成為一名小小架構師夢想,深知架構師不是想想就成的。

吾已工作過一陣子,吾妄想在真正畢業之后工作一年左右就能拿到那個數ten thousand的工資。勿噴!

 

我們成長的環境不同,也許有人一手栽培,也許只能一個人默默奮斗。不論怎樣,

我們要先學會造輪子,但我只會造4個高質量的輪子。讓我的車子穩健地跑起來!

深知實現這些規划,我必須要付出常人難以付出的努力!

 

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

更希望能給讀者帶來一些新的認識及知識。

各位大神,請點支持一下小弟。最后我會為看官上傳源碼+數據庫。

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

上篇銜接

篇二中通過一個工廠造出一個線程內唯一的繼承IDBContact的DBContact。

並通過一個另一個工廠造出一個線程內唯一的繼承ObjextContext的ModelContainer寫成DBContact的屬性。

並把上下文的Savechange()封裝到DBContact里面

讓執行SQL在服務層中控制邏輯。當然去掉了倉儲層的ModelContainer的Savechange()

並把每個倉儲寫成對應的屬性。  

目的:就是業務邏輯(這里叫服務層)只通過這個類來進行訪問數據層(這里叫倉儲層)。

①DBContact.cs

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

namespace LKBS.CommunicationPlatform.DAL
{
 public class DBContact : IDBContact
 {

  public ObjectContext currentEFContext { get; set; }
  ISingleEFCntextFactory singleEFCntextFactory = new SingleEFCntextFactory();//SingleEFCntextFactory做到單一DBContact
  public DBContact()
  {
   currentEFContext = singleEFCntextFactory.GetCurrentEFContext();//
  }

  public int excuteSQL(string cmdText, SqlParameter[] parammeters)
  {
   return currentEFContext.ExecuteStoreCommand(cmdText, parammeters);
  }
  //在倉儲層BaseRespository就不用savechang了,讓其在服務層控制提交數據庫
  //放在服務層這就是業務邏輯,根據業務邏輯層的一個場景,簡單說一個方法中可能用到多個表。最后執行保存。做到和數據庫交互一次
  public int saveChange()
  {
   return this.currentEFContext.SaveChanges();
  }
  public IUserInforRespository userinforResponsity { get; set; }
 }
}

②IDBContact.cs

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

namespace LKBS.CommunicationPlatform.IDAL
{
  public interface IDBContact
   {
    //接口中的屬性要{}
    ObjectContext currentEFContext { get; set; }
    int excuteSQL(string cmdText, SqlParameter[] parammeters);
     int saveChange();
    IUserInforRespository userinforResponsity { get; set; }
    //...多個其他表的倉儲,在T4模板中加OK
   }
}

重點查看

 

⑥BaseService.cs中的獲得倉儲層的實例的邏輯。

為了獲得實例我們在我們在BaseService中寫一個獲得實例的抽象方法,

為了必須在自類繼承並保證在子類④UserInforService必須實現此方法,我們把BaseService寫成了一個抽象類。必須寫成!

什么時候執行呢?當子類實例化的時候,會調用基類構造方法。所以我們在基類的構造函數中調用這個獲得實例的抽象方法。

 

ok,說了這么一大通,其實就是對抽象類和抽象方法的實踐運用。還有實踐運用子類實例化會調用基類構造方法這點!

最后,這一大通就是一個循環。理解了就會這樣覺得。這種方式實現了 子類掉基類 基類調子類循環

 

服務層的創建

在這個層搭建的過程中,我漏洞百出,木有public或者木有程序集引用或者木有using,接口對象掉不出實例接口中已經具備的方法,老是警告。

不能直接賦值非靜態變量或者屬性或者方法等,最終還是都解決了。最終的程序沒有一個警告。全部通過。

框架搭的差不多了。數據庫其實我已經建好,只是沒發上來。

下篇我就要開始搭前台了。

這個過程中,就是一個成長的過程,我要記錄下來。以后少出這樣的錯。即使出錯,我會很快的改正。

③IUserInforService.cs

using LKBS.CommunicationPlatform.Model;

namespace LKBS.CommunicationPlatform.IBll
{
 public interface IUserInforService : IBaseService<UserInfor>
  {

  }
}

④UserInforService.cs

using LKBS.CommunicationPlatform.IBll;
using LKBS.CommunicationPlatform.Model;
using LKBS.CommunicationPlatform.IDAL;
using LKBS.CommunicationPlatform.DAL;


namespace LKBS.CommunicationPlatform.Bll
{
  public class UserInforService:BaseService<UserInfor>, IUserInforService
   {
     public override void setCurrentRespository()
     {//此時點不出父類的dbContact 因為這個字段沒有public
       this.currentRespository = this.dbContact.userinforResponsity;
     }
   }
}

⑤IBaseService.cs

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

namespace LKBS.CommunicationPlatform.IBll
{
 public interface IBaseService<T>
  {
  bool AddEntity(T entity);
  bool DeleteEntity(T entity);
  bool UpdateEntity(T entity);
  T SelectOneEntity(Func<T, bool> wherelamda);
  IQueryable<T> SelectAllEntityList(Func<T, bool> wherelamda);
  IQueryable<T> SelectPageEntityList<S>(Func<T, S> orderLamda, Func<T, bool> whereLamda, int pageIndex, int pageSize, bool isAsc, out int rowcount);
  }
}

⑥BaseService.cs

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

using LKBS.CommunicationPlatform.Model;
using LKBS.CommunicationPlatform.IDAL;
using LKBS.CommunicationPlatform.DAL;
using LKBS.CommunicationPlatform.Factory;
using System.Data.Entity;
using System.Runtime.Remoting.Messaging;


namespace LKBS.CommunicationPlatform.Bll
{
 public abstract class BaseService<T> where T : class,new()
 {
  //未添加程序集:using;類木有public 都能找不能這個類
  ISingleDBContactFactory singleDBContactFactory = new SingleDBContactFactory();
  public IDBContact dbContact;
  public BaseService()
  {
   dbContact = singleDBContactFactory.CreateDBCotactUseEF();
   //獲取當前的倉儲實例   重點邏輯!!!!! 將此類寫成抽象類,子類必須實現。
   //子類實例化時候,調用基類狗狗函數 ,構造函數執行基類虛方法,基類虛方法有調用子類實現的方法。然后繼續執行基類下面代碼
   //這個邏輯才是真正對面向對象的理解和抽象類的使用的精髓使用。!!
   setCurrentRespository();
  }
  public abstract void setCurrentRespository();
  //錯誤    2    類型“T”必須是引用類型才能用作泛型類型或方法
  //忘記在類中加上where T:class,new()
  public IBaseRespository<T> currentRespository;

  public bool AddEntity(T entity)
  {
   currentRespository.AddEntity(entity);
   if (dbContact.saveChange() > 0)  //找不到saveChange,接口中沒有此方法,但子類有0.0
   {
    return true;
   }
   else
   {
    return false;
   }
   
  }

  public bool DeleteEntity(T entity)
  {

   currentRespository.DeleteEntity(entity);
   
   if (dbContact.saveChange()>0)
   {
    return true;
   }
   else
   {
    return false;
   }
 
  }

  public bool UpdateEntity(T entity)
  {
   currentRespository.UpdateEntity(entity);
   if (dbContact.saveChange()>0)
   {
    return true;
   }
   else
   {
    return false;
   }
  
  }
  /// <summary>
  /// 單個實體
  /// </summary>
  /// <param name="wherelamda"></param>
  /// <returns></returns>
  public T SelectOneEntity(Func<T, bool> wherelamda)
  {
   return currentRespository.SelectOneEntity(wherelamda);
  }
  /// <summary>
  /// 查詢 整張表或者多個實體 
  /// </summary>
  /// <returns></returns>
  public IQueryable<T> SelectAllEntityList(Func<T, bool> wherelamda)
  {
   return currentRespository.SelectAllEntityList(wherelamda);
  }
  int rowcount = 0;
  //泛型方法 <S>就是約束參數的類型,傳什么參數,“自動識別”<S>. 定義需要<S>,調用該方法可以省略 :因為傳的參數就已確定<S>的類型
  public IQueryable<T> SelectPageEntityList<S>(Func<T, S> orderLamda, Func<T, bool> whereLamda, int pageIndex, int pageSize, bool isAsc, out int rowcount)
  {//非頁數pageCount,是總行數
   return currentRespository.SelectPageEntityList<S>(orderLamda,whereLamda, pageIndex, pageSize, isAsc, out rowcount);
   }
  }

 }

下篇銜接

數據庫我已經建好,當然還有需要完善數據庫的地方,畢竟需求的分析是要變化的。

最后我會發上來,現在不發,因為架構用不到數據庫。最后看官親自動動手調試的時候,我自會奉獻上。這算是小小的“干貨”吧。自勉

T4模板的使用,對數據庫表的生成,完善和數據庫表的全部映射。

下篇我就開始搭前台了。這個估計要幾天才能搞定。

 

 

 


免責聲明!

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



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