.Net Core建站(3):搭建三層架構


啊,終於到寫三層架構的時候了,老實說,我都不知道自己這個算不算三層架構,姑且就當它是吧,具體屬於哪一個體系,希望有大佬指點一下(^o^)/

不曉得有人注意到沒有,我寫了三篇博客,然后就改了三次標題ヽ( ̄▽ ̄)ノ,

從最開始的Core建數據庫,到Core數據庫操作,再到現在的Core建站,也算是下決心寫個系列啊,,感覺要更好久的樣子,,

好吧,不要在意那些細節,文中可能會有一些我不知道的坑,畢竟自己也是一邊自學一邊寫,不過保證功能還是能用的,發現有坑記得說,,我改,,(〃'▽'〃)

 

// ===================emmm,我是分割線===================

 

 強烈推薦閱讀:設計模式六大原則 講的相當淺顯易懂,,

首先上一個截圖,看看現在的項目結構,今天的主角是DataBase文件里面的那一堆項目啊,BLL,DAL和Interface,,Models是生成數據庫時使用的,所以今天用不上,,

 

按我的理解,先說說正常的三層架構吧,

UI:界面層,這個層最簡單,只是給BLL傳遞數據,然后,將BLL返回的數據進行一些處理,方便展示,

BLL:業務邏輯層,接收UI層給的數據,寫一些業務邏輯,第一步干啥,第二步干啥,什么什么的,然后把界面需要的數據返回出去,感覺更像是一個API

DAL:數據訪問層,BLL的業務邏輯處理時,總要涉及到數據庫的操作,這時候就要用到DAL層了,,

還有一個Model層,用來傳遞數據的,,不在三層范疇,,,

 

不知道大家是怎么使用三層的,給大家展示一下以前學校教我們怎么用的三層架構啊,,

分別對應三個類,UI層:HomeController,BLL層:DT_UserBLL,DAL層:DT_UserDAL

 1         // UI層
 2         public IActionResult Index(int userID)
 3         {
 4 
 5             // 根據條件,返回用戶
 6             // 和BLL說,給你一堆條件,幫我把這些人找出來
 7             var userList = DT_UserBLL.GetUser(0,18);
 8 
 9             return View(userList);
10 
11         }
 1         /// <summary>
 2         /// BLL層,返回符合條件的用戶
 3         /// </summary>
 4         /// <param name="sex">性別</param>
 5         /// <param name="age">年齡</param>
 6         /// <returns></returns>
 7         public List<DT_User> GetUser(int sex, int age)
 8         {
 9 
10             #region 數據校驗
11 
12             // 性別檢測,0:女,1:男
13             if (sex != 0 && sex != 1)
14                 // 拒絕人妖
15                 return null;
16 
17             // 年齡檢測,[0,150]歲
18             if (age < 0 || 150 < age)
19                 // 拒絕妖怪
20                 return null;
21 
22             #endregion
23 
24             // 和DAL說,數據我校驗好了,不是惡搞,
25             // 幫我查出來這些人,然后我交給UI就完事兒了,,
26             return DT_UserDAL.GetUser(int sex, int age).ToList();
27         }
 1         /// <summary>
 2         /// DAL層,返回符合條件的用戶
 3         /// </summary>
 4         /// <param name="sex">性別</param>
 5         /// <param name="age">年齡</param>
 6         /// <returns></returns>
 7         public IQueryable<DT_User> GetUser(int sex, int age)
 8         {
 9             DbContext DB = new DbContext();
10 
11             return DB.Set<DT_User>().Where(c=>c.Sex==sex&&c.Age==age);
12         }

當時學着感覺蠻好的,挺新奇的一個編程思想,不過每一個數據表對應的DAL里面都得寫一套增刪查改,,簡直是災難,,[○・`Д´・ ○]

出來實習之后,花了個把星期,把我們老大寫的一個框架看明白了,就按圖索驥地寫了起來,嘿嘿

 

其實和三層架構差不多的,只是把每個數據表對應的DAL里面的增刪查改全部提出來,封裝成了一個類,,

然后對這個類進行繼承,具體操作如下,,,

 

首先啊,要大概了解一下依賴注入,,講真,這個我也是一臉懵逼,所以就不復制百度百科了,,

說說自己的理解吧,,,,emmm,此處可能有大量謬論,建議不要被我誤導了,看看就好,別往心里去

依賴注入這東西就好像一個全局的字典類型變量,,都是以鍵值對的方式存儲的

因為注冊依賴注入服務的大部分語法是醬紫的,,,

1 services.AddTransient(typeof(IDT_UserService), typeof(DT_UserService));

而services這個變量的話,就像一個容器,用來存儲這些鍵值對的,具體從哪來的,我也不知道,ヽ( ̄д ̄;)ノ

而要使用的話,語法是醬紫的,,,

 1     public class HomeController : Controller
 2     {
 3         private IDT_UserService _UserService;
 4 
 5         public HomeController(IDT_UserService _UserService)
 6         {
 7             // 依賴注入得到實例
 8             this._UserService = _UserService;
 9         }
10 
11         public IActionResult Index()
12         {
13             ViewBag.list = _UserService.LoadEntites(c => true);
14 
15             return View();
16         }
17     }

對的,完全不需要new,,其原理,,起碼我不曉得,感覺甚是神奇,,

先注冊一個依賴注入的服務,然后要實例的時候,直接在構造函數里面把鍵的類型寫上就好,,

好了,灌毒就到此為止了,,還是繼續上代碼吧,,

 

首先,得寫一個數據庫操作的底層類DalService又因為很多地方調用,所以,肯定是泛型,,

然后為了解耦和方便注入,所以實現一個接口IDalService

我暫時只寫了添加和查詢的方法,,其他的方法可以自由發揮,,不過記得先寫接口,然后去實現接口中新加的方法,,不然無法使用的,,

1     public interface IDalService<T> where T : class, new()
2     {
3         T AddEntity(T entity);
4 
5         IQueryable<T> LoadEntites(Expression<Func<T, bool>> where);
6 
7         int SaveChanges();
8 
9     }
IDalService
 1     /// <summary>
 2     /// 數據訪問層:DAL
 3     /// </summary>
 4     /// <typeparam name="T"></typeparam>
 5     public class DalService<T> : IDalService<T> where T : class, new()
 6     {
 7 
 8         private DbContext DbWrite;
 9         
10         /// <summary>
11         /// 獲得數據庫上下文
12         /// </summary>
13         /// <param name="dbContext">數據庫上下文類,各自更改成自己的</param>
14         public DalService(DBCodeFirst dbContext)
15         {
16             DbWrite = dbContext;
17         }
18 
19         public T AddEntity(T entity)
20         {
21             DbWrite.Set<T>().Add(entity);
22             return entity;
23         }
24 
25         public IQueryable<T> LoadEntites(Expression<Func<T, bool>> where)
26         {
27             return DbWrite.Set<T>().Where(where);
28         }
29 
30         public int SaveChanges()
31         {
32             return DbWrite.SaveChanges();
33         }
34 
35     }
DalService

然后就沒有DAL層啥事了,,咱們去看BLL層

 

同樣的寫一個業務邏輯的父級類BllService,依舊是泛型,以及實現接口IBllService

1     public interface IBllService<T>where T : class, new()
2     {
3         T AddEntity(T entity,bool IsSave);
4 
5         IQueryable<T> LoadEntites(Expression<Func<T, bool>> where);
6 
7         int SaveChanges();
8     }
IBllService
 1     /// <summary>
 2     /// 數據邏輯層:BLL
 3     /// </summary>
 4     public class BllService<T> : IBllService<T> where T : class, new()
 5     {
 6 
 7         /// <summary>
 8         /// 數據庫服務
 9         /// </summary>
10         protected IDalService<T> DBService;
11 
12         public BllService(IDalService<T> dalService)
13         {
14             this.DBService = dalService;
15         }
16 
17         /// <summary>
18         /// 保存實體
19         /// </summary>
20         /// <param name="entity"></param>
21         /// <param name="IsSave"></param>
22         /// <returns></returns>
23         public T AddEntity(T entity, bool IsSave)
24         {
25             entity = DBService.AddEntity(entity);
26             if (IsSave)
27             {
28                 if (SaveChanges() > 0)
29                     return null;
30             }
31             return entity;
32         }
33 
34         /// <summary>
35         /// 查詢數據
36         /// </summary>
37         /// <param name="where"></param>
38         /// <returns></returns>
39         public IQueryable<T> LoadEntites(Expression<Func<T, bool>> where)
40         {
41             return DBService.LoadEntites(where);
42         }
43 
44         /// <summary>
45         /// 保存數據庫
46         /// </summary>
47         /// <returns></returns>
48         public int SaveChanges()
49         {
50             return DBService.SaveChanges();
51         }
52     }
BllService

 

然后基本就完成了,,我們可以在BLL層創建一個DT_User的邏輯處理類,繼承BllService,並實現接口IDT_UserService

1     public interface IDT_UserService : IBllService<DT_User>
2     {
3         DT_User Insert();
4 
5         List<DT_User> GetList();
6     }
IDT_UserService
 1     public class DT_UserService : BllService<DT_User>, IDT_UserService
 2     { 
 3         /// <summary>
 4         /// 用於實例化父級,DBService變量
 5         /// </summary>
 6         /// <param name="dal"></param>
 7         public DT_UserService(IDalService<DT_User> dal) : base(dal)
 8         {
 9 
10         }
11 
12         public DT_User Insert()
13         {
14             DT_User user = new DT_User
15             {
16                 Password = new Random().Next(0, 101) + "",
17                 UserName = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
18             };
19             return AddEntity(user, true);
20         }
21 
22         public List<DT_User> GetList()
23         {
24             return LoadEntites(c => true).ToList();
25         }
26 
27     }
DT_UserService

 

最后使用的話,要把他們統統注冊到服務里面,新建一個類DIBllRegister,用來注冊這些和數據庫相關的服務

 1     /// <summary>
 2     /// Bll層依賴注入
 3     /// </summary>
 4     public class DIBllRegister
 5     {
 6 
 7         public void DIRegister(IServiceCollection services)
 8         {
 9             // 用於實例化DalService對象,獲取上下文對象
10             services.AddTransient(typeof(IDalService<>), typeof(DalService<>));
11 
12             // 配置一個依賴注入映射關系 
13             services.AddTransient(typeof(IDT_UserService), typeof(DT_UserService));
14         }
15     }
DIBllRegister

Startup的ConfigureServices方法中添加兩行代碼

 1         /// <summary>
 2         /// 運行時調用此方法。使用此方法向容器添加服務。
 3         /// </summary>
 4         /// <param name="services"></param>
 5         public void ConfigureServices(IServiceCollection services)
 6         {
 7             services.AddOptions();
 8 
 9             // 數據庫連接字符串
10             var conStr = Config.GetVal<string>(ConfigKey.ConStr);
11             services.AddDbContext<DBCodeFirst>(options => options.UseSqlServer(conStr));
12 
13             DIBllRegister bllRegister = new DIBllRegister(); 14  bllRegister.DIRegister(services); 15             
16             services.AddMvc();
17         }

 

然后我們就可以愉快的使用三層架構來寫項目了,,ヽ(≧∀≦)ノ

示例以及項目結構如下:

運行結果:

 

 注意事項:

  1. BLL層的類一定要繼承BllService,並實現它對應的接口,參考上文DT_UserService類的格式
  2. BLL,DAL任何類要添加方法時,一定要在對應的接口中有個同樣的入口,不然無法調用
  3. BLL層添加類時,記得在DIBllRegisterDIRegister中添加一行注冊服務的代碼,不然無法調用
  4. 差不多就這些,我想起來了再加,,,

 

其實這個是我從Framework搬過來的,心塞得簡直不要不要的,,,填坑日記就不寫出來了,,

具體的搭建思想也不太好用文字表述,大佬不要吐槽,萌新可以照着步驟去建一個小項目調試着看,,

個人感覺還是比較好懂的,,畢竟,基本上全是核心代碼還帶注釋,加一個使用樣例,

 

然后就是下集預告了,雲服務器的FTP發布和數據庫連接吧,,畢竟雲服務器到手辣么久了,也該拉出來溜溜,,(❁´◡`❁)*✲゚*

最后,,有坑記得說,,,,

 


免責聲明!

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



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