Asp.net 面向介面框架之應用程式上下文作用域組件

来源:http://www.cnblogs.com/xiangji/archive/2016/04/20/5415080.html
-Advertisement-
Play Games

在團隊中推廣面向介面開發兩年左右,成果總體來說我還是挺滿意的,使用面向介面開發的模塊使用Unity容器配置的功能非常穩定,便於共用遷移(另一個項目使用只需要複製配置和調用介面即可)也很好擴展(操作的資料庫、表、資源等都可以配置)。 但是由於當時開發的匆忙(邊開發邊應用),留下一些比較致命的問題: 1 ...


在團隊中推廣面向介面開發兩年左右,成果總體來說我還是挺滿意的,使用面向介面開發的模塊使用Unity容器配置的功能非常穩定,便於共用遷移(另一個項目使用只需要複製配置和調用介面即可)也很好擴展(操作的資料庫、表、資源等都可以配置)。

但是由於當時開發的匆忙(邊開發邊應用),留下一些比較致命的問題:

1、很多介面定義的不合理,通用性和擴展性不好

2、固定死了使用Unity容器,如果更大面積推廣有問題,有些人已經很熟悉其他容器了,再來重新學Unity沒有必要

3、配置比較麻煩,需要簡化

所以我覺得有必要重新開發一個框架,對原框架取其精華去其糟粕,再吸收開源項目(含微軟開放源代碼的部分),爭取做出一個像樣一點的東西並開源出去...

這裡插一句,前面有寫一個Asp.net Mvc分區擴展框架系列沒有寫完的原因,其一是趕時間做這個框架,其二是重新做新框架,所有剩下的文章按新的框架來寫會更好


 這裡要講的是本框架中一個小的組件,應用程式上下文組件(AppContext),本組件有參考博客園大神的文章,這裡先不註明出處(如果文章的作者介意,我再修改博文標註)

下麵開始介紹本組件的主要使用場景

1、不同對象和方法間傳遞數據的新方式,看例子

看運行結果:

有人會說,你就作吧,修改一下A方法返回那個隨機數,修改B方法增加一個參數接受這個隨機數,So Easy。

但是在現有完成架構上增加一個附屬功能,就把簽名改了是很恐怖的事情。實際項目中產生對象方法和其他需要調用對象的方法可能沒有調用鏈,或者調用鏈非常複雜,你要把涉及的所有方法都改一邊,那系統估計差不多要被你改"廢"了

在現實項目中並不推薦大規模的這樣使用,只有在擴展附屬功能,Aop或者在現項目擴展需要,慎重之下一個解決方案而已,性能肯定是比直接傳要差不少,權當是應用程式上線文緩存來使用。

以上代碼按照預期的效果運行了,看似簡單功能,後面原理還是挺複雜的

2、線程安全調用

以上用兩個線程對上下文中讀取和寫入數據,看數據是否會串(線程是否安全),看執行結果:

稍微解讀一下:

      A:線程6先運行,從上下文中讀取鍵為test類型string的值為空,阻塞1000毫秒,再寫入鍵為test,類型為string的值1000,再阻塞1000毫秒

      B:線程11從上下文中讀取鍵為test類型string的值為空,阻塞14毫秒,再寫入鍵為test,類型為string的值14,後阻塞14毫秒

      C:線程11從上下文中讀取鍵為test類型string的值為14

      D:線程6從上下文中讀取鍵為test的string的值為1000

      E:兩個線程交替運行,各自讀取和寫入的值互不影響

      所以建議定義全局靜態變數的就省省吧,那樣線程不安全,危險很大

3、有人會提到HttpContext

     確實HttpContext.Current.Items可以實現這樣的效果,但是HttpContext.Current並不是無處不在,非Web應用程式為null

     就算是Web項目也不能濫用HttpContext.Current,在非同步線程裡面該屬性也是null,不信的可以試試

     但是HttpContext.Current還是很有用的,我這裡實現的AppContext就有調用HttpContext.Current,如果為null,再調用另一個更神秘的東西CallContext

     大家看一下實現代碼:

     在web程式中有非同步操作會有線程切換,需要線程間複製上線文對象,使用HttpModule(以下代碼來自一個博客園大神,我幾乎沒改)

4、服務(配置)作用域

4.1 先看建模代碼

稍微解讀一下:

       A:Greet是用來打招呼,name對who發一個問候語

       B:Person明顯就是代表一個人,其中有一個Chindren屬性,代表從屬子對象(為了簡化使用相同類型)

       C:Person有一個Sayer屬性,用來對其他"人"打招呼的

       D:從方法Greet(Greet sayer, Person person)可以看出,如果取不到sayer對象會打招呼失敗(提示sayer is miss)

       E:對另一個對象Great的時候會遍歷每個子對象分別對那個對象"問候"一下(這家的小孩還真有禮貌,大人問候誰,每個小孩都問候他)

4.2 再看測試代碼

也解讀一下:

      A:定義了a,a1,b及a的另一個子對象

      B: 其中只有a對象設置了Sayer屬性

      C:a對象Great了b(其中隱含a的所有子對象都對b進行Greate),之後a1對象單獨Greate了一下b

4.3 看運行結果

哈哈,看到結果是不是有點驚訝啊

    A:a對b的Hello是成功的很正常,但是a的兩個子對象也對b的Hello成功了

    B:更神奇的是,a1單獨對b的Hello缺是失敗的(不是繼承了父對象的屬性)

    C:這裡對上線文又進了一步,是作用域,只有a對b使用自己的Sayer屬性時,其他對象(不一定是自己的子對象)也可以截獲Sayer的值,但是等a對象使用完畢後就回收了,其他人就用不了了

4.4 原理解析

    

    這裡有一個using的作用域,AppContext.CreateResource在上線文中註冊或者查找類型為Greate名字為A的,候選值為Sayer的對象,保存在resource.Entity中

4.5 來看一下實現的源代碼

 

      哈哈,是不是有點複雜啊

     A:實現IDisposable以便使用using來控製作用域

     B:Dispose也不是簡單的就把作用域的對象刪除,如果_needDispose為false不刪除對象(不是自己創建的對象無權刪除)

     C:除了刪除有的時候還要Restored(_needRestored為true),自己的作用域結束,把備份的_entity0還回去

     D:Init方法嘗試從作用域獲取對象並備份到_entity0,如果本次候選對象無效直接使用作用域已有對象,如果有效就覆蓋作用域(有_entity0備份能還原回來)

     E:是不是非常有意思,就像定義變數一樣,小作用域可以覆蓋上級作用的變數,離開小作用域,外面作用域的變數又可以使用了

5、作用域的作用

  5.1 我特意開發這個功能是用來簡化系統配置的

      5.2 比如日誌(含異常調試日誌)幾乎是每個對象都需要的功能

    如果每個對象都配置這些通用屬性,配置的工作量太大了,配置文件太亂了

           如果硬編碼寫死,那豈不就倒退到八百年前了

           並不是所有都不配,只把特殊需要的配置,如果需要日誌在最外面配置(或者只初始化一個作用域),裡面調用的子對象也都可以共用外層的配置(共用日誌服務)

           有人可能說衝突了怎麼辦,可以用name隔離

6、應用程式上下文緩存

    

      這個緩存的作用域只能是當前會話(線程或者Request),所以天生的線程安全(所以那個字典我都沒用ConcurrentDictionary)

      有人可能要笑話我,緩存不都是分散式嗎?你那個緩存利用率太低了吧?

      是的,你要說緩存利用率,確實不能和分散式比。但是要想到這個比session還session(不用清除下次請求重新初始化,也不用擔心被人杜撰(修改sessionId))的高速緩存(直接字典)

      自然也和session一樣不用擔心用戶數據會串、存放用戶登錄狀態、許可權等都不是問題

      用起來簡單的不得了,直接New就可以使用,哪怕定義一個全局靜態變數都是“線程(會話)安全”的,也可以配置在容器裡面放心使用

 

      測試項目下載

      該組件暫時就先寫這麼多吧。寫這篇文章的目的除了給大家分享自己的東西外,最主要的還是想得到博客園大神的指導,因為框架一旦開始使用再做調整就很要命,其一希望框架能做的更通用更好用,大家一起使用。其二把可能的問題儘早的發現,在正式使用之前更加完善。有些硬傷,比如介面、方法簽名定義等如果不合理推廣後就不好修改了,可能只能作為框架的缺陷存在了。介面一改,依賴這個介面的所有實現類都要改,很恐怖的。也是因為原來開發匆忙的框架“缺陷”太多,我不得不下定決心開發新框架。

      這麼多天每天長時間寫代碼,每天加班加點都寫得全身冒汗,也寫出了不少代碼,卻是今天下班後第一次調試,並且調試通過了一個我非常喜歡的上線文作用域組件(當然還有優化的地方)

      下麵簡單介紹一下這個框架:

      以下是項目解決方案截圖:

    A:第一張圖是解決方案,部分擴展功能項目,這些需要很多人參與進來完善

    B:後面的四張圖是框架主項目的截圖,大部分都是已經開發完成但還未測試的功能,其後是大量測試改bug和完善功能

         主框架及相關項目我會在這裡系列裡面逐個測試優化後在發佈出來,希望大家一起幫忙看一下,提供意見和建議

    C:主框架本身並不力求解決所有方法,而是定義一些通用功能、邏輯的介面,對部分介面提供預設實現及部分“設計模式”功能,其他功能在其他項目中再擴展實現

    D:主框架不含對具體哪種資料庫或者哪種ORM工具的調用和不含具體開源外部日誌組件和容器等調用(這些應該在外部擴展項目中對接)

    E:該框架並不是要推翻系統的東西,而是整合,增加擴展性,給程式員帶來更多便利和選擇

    F:總之主框架主要是抽象主要介面、實現部分非常通用的功能,儘量少引用外部

    G:其他功能儘量繼承按主框架的介面來開發,以便方便集成到主框架,或者其他模塊間相互調用卻不相互引用

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 磁碟分析 本機的系統盤是C盤,操作系統是Windows 7 專業版,通過磁碟屬性可以看到C盤的已用空間是69.4G。 而我們運行自己編寫的腳本(腳本程式參考附錄,統計原理:計算目錄下各個文件的大小,然後相加,即為該目錄的大小;再將各個目錄占用空間相加,即為總的占用空間),可以發現,占用空間為59G。 ...
  • 由於需要安裝hadoop集群,有10台機器需要安裝,一開始打算用SCP複製,後來覺得不可接受(實際現場可能數倍的機器集群,就是10台也不想乾)。後來在網上找了,發現了clustershell和pssh這兩個工具。這兩個工具隨便用其中一個就可以了。 環境說明:centos6.5機器10台 需求:確定一... ...
  • 我第一次接觸“線程”的概念時,覺得它深奧難懂,看了好多本書,花了很長時間才領悟到它的真諦。現在我就以一個初學者的心態,把我所理解的“多線程”描述給大家。這一次是系列文章,比較完整的展示與線程相關的基本概念。希望對初學者有所幫助。 如果你是高手,請你別繼續看,會浪費你寶貴的時間。 一、基本概念 什麼是 ...
  • 我們在做開發的時候,很多時候需要和Json數據格式打交道,如Web開發裡面,很多時候,數據通過Json進行傳遞到頁面上,然後在進行處理的。而使用Json的時候,我們很多時候會涉及到幾個序列化對象的使用:DataContractJsonSerializer,JavaScriptSerializer 和 ...
  • 概述 BPEL:全稱為Business Process Execution Language,即業務流程執行語言,是一種使用XML編寫的編程語言。用於自動化業務流程,也曾經被稱作WSBPEL和 BPEL4WS。廣泛使用於Web服務相關的項目開發中,優點為具有可移植性和有效保護了投資。 BPEL是一門 ...
  • c# 操作 xml 在System.XMl 有以個類可以操作xml (網上對這些類的記錄真得很少啊 可能因為類比較多吧 msdn的介紹) 創建一個新的xml XmlDocument xmldoc = new XmlDocument(); //在XML的文檔的最頭部加入XML的聲明段落 XmlNode ...
  • 分類:Unity、C#、VS2015 創建日期:2016-04-21 一、簡介 Unity提供了—個非常易用和強大的用於處理輸入信息的類:Input,利用該類可以處理滑鼠、鍵盤、搖桿/方向盤/手柄等游戲外設,也可以處理iOS/Androd等移動設備的觸摸輸入信息。 程式員通過編寫腳本接收輸入信息,完... ...
  • 控制反轉IOC, 全稱 “Inversion of Control”。依賴註入DI, 全稱 “Dependency Injection”。 面向的問題:軟體開發中,為了降低模塊間、類間的耦合度,提倡基於介面的開發,那麼在實現中必須面臨最終是有“誰”提供實體類的問題。(將各層的對象以松耦合的方式組織起 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...