01 | 模塊化方案一html
02 | 模塊化方案二git
01 | 前言github
04 | 強化設計方案設計模式
06 | 最終篇-經過AOP自動鏈接數據庫-完成日誌業務app
項目涉及到了一些設計模式,若是你看的不是很明白,沒有關係堅持下來,寫完以後去思考去品,你就會有一種突撥開雲霧的感受,因此請不要在半途感受本身看不懂選擇放棄,若是我哪裏寫的詳細,或者須要修正請聯繫我,謝謝。框架
咱們開發用的vs版本是2019 .Net Core的版本是3.1
下載 SDK 地址 :https://dotnet.microsoft.com/downloadasync
這裏選擇Core 版本是3.1 項目類型是API
Docker支持咱們不勾選,我會在後續給你們單獨再開一個系列 咱們專講,慢慢來。
這裏能夠看到一個很是乾淨的項目就建立出來了,項目結構就是這樣,裏面的詳情能夠去看老張的第二個章節,講的很明白,我就不在重複了
http://www.javashuo.com/article/p-nfleduql-u.html
進階能夠去看開源源碼 https://github.com/aspnet/MetaPackages/tree/master/src/Microsoft.AspNetCore
而後咱們直接F5 啓動項目看看 是否是新建的項目是否是沒有問題,項目一切正常,咱們開始進入正軌。
分表這個功能,就是把相同結構不一樣名稱的多張表數據讀取出來,這個部分其實很簡單,咱們常見的ORM都支持切換表名進行查詢。
分庫如何實現呢。
先來看一下咱們經常使用的ORM框架是如何鏈接數據庫的。
SqlSugar鏈接數據庫
FreeSql鏈接數據庫
它們有一個共同點,NEW一個對象傳遞數據庫鏈接字符串,設置好數據庫類型,各自的xxx配置,就會獲得一個鏈接的Client,而後就能夠進行CRUD了。
那New多個對象,每一個對象都是不一樣的鏈接字符串豈不是就能夠操做多個數據庫了。
你們寫代碼可別直接在業務/數據訪問層這麼寫,整很差就讓你下班領盒飯了。
那麼這種情境下因該如何設計能讓代碼更加規範、易擴展呢!
思路就是這樣,那麼若是讓你來設計,你會怎麼作呢,你們能夠本身嘗試着先去根據本身想法設計看看,而後咱們下一節,我來給講解個人設計方案。
爲了提升難度設計難度咱們來同時兼容FreeSql、SqlSugar2款如今最熱門的ORM。
咱們設計要作到:
該接口規範字典操做標準方法。
這裏使用的ConcurrentDictionary 是一個併發字典。
public interface IAnyStorage<T> where T : class { ConcurrentDictionary<string, T> DataMap { get; } T GetByName(string name, string defaultName); void AddOrUpdate(string name, T val); void Remove(string name); void Clear(); }
咱們先作SqlSugar的版本
繼承IAnyStorage由於他是泛型繼承它,咱們須要傳遞一個參數,他是什麼呢?固然是咱們的SqlSugar鏈接提供程序了。
咱們安裝NuGet包安裝 sqlSugarCore
public class DefaultSqlSugarProviderStorage : ISqlSugarProviderStorage { public ConcurrentDictionary<string, ISqlSugarProvider> DataMap { get; private set; } public DefaultSqlSugarProviderStorage(IServiceProvider serviceProvider) { DataMap = new ConcurrentDictionary<string, ISqlSugarProvider>(); var tmpDataMap = serviceProvider.GetServices<ISqlSugarProvider>() .ToDictionary(item => item.ProviderName); foreach (var item in tmpDataMap) { this.AddOrUpdate(item.Key, item.Value); } } public void AddOrUpdate(string name, ISqlSugarProvider val) { DataMap[name] = val; } public void Clear() { DataMap.Clear(); } public ISqlSugarProvider GetByName(string name, string defaultName) { ISqlSugarProvider result = null; if (name == null) { if (!DataMap.TryGetValue(defaultName, out result)) { throw new Exception("沒有找到 DefaultName Provider"); } return result; } else if (DataMap.TryGetValue(name, out result)) { return result; } throw new ArgumentException($"沒有找到 {name} Provider"); } public void Remove(string name) { if (string.IsNullOrWhiteSpace(name)) { return; } this.DataMap.TryRemove(name, out ISqlSugarProvider result); } }
字典的操做我想都能看明白,基礎差的朋友可能會以爲不懂的就是下面這句,這是作什麼呢,其實就是咱們把注入ISqlSugarProvider的實現都查詢
出來,放到咱們的DateMap集合中(好處後面我會實踐給你們講到),到此咱們SqlSugar鏈接提供程序存儲庫就完成了。
var tmpDataMap = serviceProvider.GetServices<ISqlSugarProvider>() .ToDictionary(item => item.ProviderName); foreach (var item in tmpDataMap) { this.AddOrUpdate(item.Key, item.Value); }
差點SqlSugar鏈接提供程序的實現給漏了。
咱們在 Impl 文件夾 新建 SqlSugarProvider類,繼承ISqlSugarProvider接口。
public class SqlSugarProvider : ISqlSugarProvider { public string ProviderName { get; set; } public SqlSugarClient Sugar { get; set; } public SqlSugarProvider() { this.Sugar = this.CreateSqlSugar(); this.ProviderName = "DefaultSqlSugar"; } private SqlSugarClient CreateSqlSugar() { // todo 臨時 var db = new SqlSugarClient( new ConnectionConfig() { ConnectionString = "server=.;uid=sa;pwd=@jhl85661501;database=SqlSugar4XTest", DbType = DbType.SqlServer,//設置數據庫類型 IsAutoCloseConnection = true,//自動釋放數據務,若是存在事務,在事務結束後釋放 InitKeyType = InitKeyType.Attribute //從實體特性中讀取主鍵自增列信息 }); return db; } public void Dispose() { this.Sugar.Dispose(); } }
CreateSqlSugar 方法是我從SqlSugar官方複製過來的,你們注意把ConnectionString改爲本身的數據庫鏈接。
咱們如今來配置一下 Startup 先看看效果。
public void ConfigureServices(IServiceCollection services) { // 注入 services.AddSingleton<ISqlSugarProvider, SqlSugarProvider>(); services.AddSingleton<ISqlSugarProviderStorage, DefaultSqlSugarProviderStorage>(); services.AddControllers(); }
app.Use(async (context, next) => { var sqlStorage = app.ApplicationServices.GetService<ISqlSugarProviderStorage>(); var sugarClient = sqlStorage.GetByName(null, "DefaultSqlSugar").Sugar; Console.WriteLine("查看sugarClient"); });
咱們成功的從SqlSugar鏈接提供程序存儲中,拿到SqlSugarClient鏈接。
下面代碼是我在技術羣裏看到使用FreeSql的方式,這麼寫沒有問題簡單單例的實現,我推薦你們使用上文中依賴注入的方式來使用!
回顧一下本節的內容。
咱們把數據庫鏈接字符串寫在(SqlSugar鏈接提供程序)合理嗎,是否是依賴太深,這個時候咱們就用到控制反轉來下降依賴性,那麼具體怎麼作呢!