Asp.net 面向介面可擴展框架之類型轉化基礎服務

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

新框架正在逐步完善,可喜可賀的是基礎服務部分初具模樣了,給大家分享一下 由於基礎服務涉及面太廣,也沒開發完,這篇只介紹其中的類型轉化部分,命名為類型轉化基礎服務,其實就是基礎服務模塊的類型轉化子模塊 說到類型轉化必須要弄清楚.net的類型,類型都不清楚何來類型轉化 1、Primitive類型 1.1 ...


新框架正在逐步完善,可喜可賀的是基礎服務部分初具模樣了,給大家分享一下

由於基礎服務涉及面太廣,也沒開發完,這篇只介紹其中的類型轉化部分,命名為類型轉化基礎服務,其實就是基礎服務模塊的類型轉化子模塊

說到類型轉化必須要弄清楚.net的類型,類型都不清楚何來類型轉化

1、Primitive類型

     1.1 這個概念估計很多人都沒聽說過,Primitive不是一個新類型,而是.net類型中最基本的一種分類,是基元類型的意思

        MS將類型分為三類:Primitive(基元類型)、Complex(複合類型) 和 Collection(集合類型),Type 提供了IsPrimitive 屬性

     1.2 哪些類型屬於Primitive呢?

          參考鏈接:http://msdn.microsoft.com/en-us/library/system.type.isprimitive(v=vs.110).aspx

          ”The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single.“

     1.3 看到這裡還是挺失望的,我們常用的類型Decimal和String並不含在內

         有的同學可能說,別說那兩個了,裡面就除了Char和Double其他都沒用過;老實說MS真的把.net程式員徹底慣壞了

         其實Boolean就是我們常用的bool,Int32就是int,Int64就是long,Single就是float

   

     1.4 Primitive類型有什麼用呢?

         Primitive是基元類型,可以這樣理解,其他類型都是由Primitive類型構成的或者衍生的,.net對Primitive支持最好,"有些地方"對於非Primitive類型支持不好,可能造成"靈異"事件(對於一般的項目是很難碰到的,如果你能碰到,說明你對.net鑽研的比較深了,普通的工程師就更不要嚷嚷說.net類型有缺陷不敢用之說,最多底層框架開發者或者架構師小心一點)

   這裡就不展開了

2、IConvertible類型

  IConvertible並不是新維度的類型類別,IConvertible是MS定義的一個介面,我這裡講的IConvertible類型特指Ms定義的基本類型中繼承了該介面的類型

  我來稍作解析一下,繼承了IConvertible的類型非常強大,可以方便的轉化為常用的這15種類型,也正是這15種類型繼承了IConvertible介面

  也就是這15種類型可以方便的相互轉化(其實不一定的,有些轉化是會出錯的)

     IConvertible類型轉化具有高度的擴展性,可以傳一個格式化的參數(IFormatProvider)

     

 3、"基本"類型

     這裡是我定義的”基本類型“,我認為有這些類型就足夠開發使用,框架對此之外的類型不予"支持",或者這些類型優先支持

     包含類型列表:bool、byte、char、decimal、double、float、int、long、string、DateTime、byte[]

     註1:在現在記憶體這麼便宜的時代,我認為短數據類型的作用不大,短數據類型都使用int就好了

     註2:我也不喜歡使用無符號類型,所以又省略了一大批類型,對於數字類型Ms使用==0表示"邏輯空",我使用<=0表示"邏輯空",後面還有相關例子

     註3:這樣做也是情非得已,類型太多了,其排列組合更多,好在本框架是可擴展框架,使用本框架的時候可以自己擴展支持的類型,當然也可以開發一個類型擴展的組件(類庫),需要的時候自己註冊進去


 現在開始演示類型轉化基礎服務

一、類型太多,這裡先拿int類型測試

1、字元串轉int

2、不同數字類型轉化為Int

這裡我要多嘮叨一句,我前面說過對”基本類型“以外的不予支持,其實是不"支持"轉化為這些類型,這些類型轉化為”基本類型“是沒有問題的

另外,會嘗試IConvertible的類型相互轉化,如果Ms支持的很好的IConvertible轉化.這裡也沒道理不支持的

3、object轉化為int

以上例子可以看出,基本類型轉化完全沒有問題,其實在主框架,我也不打算預設實現複雜自定義類型的轉化,這個留給擴展實現

有人可能會說你上面的這些功能So easy,實現過類似功能的多如牛毛,不過是多造個輪子而已。確實,基本類型轉化實現簡單,但是這裡要強調,我做的是可擴展框架,可擴展是亮點,而且非常容易擴展

二、擴展自定義類型轉化為int的例子

1、先看自定義類型代碼

非常簡單還是解讀一下,定義了兩個類型,customObj明顯是個模型(Model)類,customConverter有一個方法傳入一個customObj對象返回一個int值

2、再看對象轉化代碼

首先我們看結果,是我們預期的效果,和customConverter的Get方法的效果一致,但是我們沒有直接調用customConverter.Get,甚至好像和customConverter類型都沒什麼關係

這裡有幾個關鍵因素,其一是GlobalServices.Convert方法是怎麼運行的;其二是GlobalServices.CreateContainer()是什麼鬼

 

三、源碼解析

1、GlobalServices.Convert方法解析

這個類型轉化還是挺複雜的,挑主要的來解讀

1.1 TryConvert是嘗試類型轉化,如果轉化失敗可以換一種方法再做

這種方式在本框架中有大量應用,其實就就形成一個”策略鏈“,每個”策略“判斷一個這個問題自己是否是自己可以處理的類型,不能處理,下一個策略繼續,這樣非常便於擴展

在TryConvert中先調用個介面IEntityConvert,轉化失敗再調用IEntityAccess用來轉化

這裡有一個特別重要的事情,就是這個介面的對象從哪裡來,這裡是來自一個容器對象,這裡很清楚的看到本框架的一個擴展點,只要往容器裡面添加"策略"就可以增強本框架的類型轉化功能,這是我為什麼說主框架不打算實現複雜的類型轉化,真的非常容易擴展

1.2 再看Convert主方法

A:先按當前類型嘗試轉化

     如果策略庫(容器註冊)裡面有當前兩種類型轉化的策略,性能是最好的,優先執行

B:轉化失敗判斷當前對象是否為空

  對象為null,放棄轉化,直接返回預設值

C:Transform.TryConvertByType

  這個簡單就是強制類型轉化,如果T是S的基類,這個時候就可以直接轉化過去,也是非常安全的 

D:再嘗試IConvertible轉化

    前面說到系統的IConvertible定義了15種基本類型的相互排列組合轉化,而且還可以使用IFormatProvider自定義轉化,這就是一個強大的轉化機器,不能不試

E:再檢測返回類型是否為string,如果是string直接調用對象的ToString()

F:最後嘗試把s對象轉化為字元串,然後把字元串轉化為目標類型(T)對象

   其實這裡把字元串作為基本數據格式,相當於與對s對象序列化為字元串,然後把字元串反序列化為T類型對象,也不怪我怎麼用,.net所有類型都有一個ToString()方法,所以string是個不錯的中間類型

功能是不是非常強大,也非常有別於很多類型轉化工具,上來先反射,獲取類型元數據,然後調用屬性和欄位,現在還沒做測試,我這種方式可能會有明顯的性能優勢,但是性能現在不是我最想考慮的問題,我現在考慮的是怎麼可以非常簡單的擴展

2、GlobalServices.CreateContainer()是什麼鬼

CreateContainer定義

A:從上面可以看出GlobalServices.CreateContainer就是一個再普通不過的容器,預設實例的容器名是GlobalServices

B:前面有提到容器是可以擴展的,只要我們使用的容器支持(比如Unity、Spring.net等),我們完全可以使用配置文件來擴展類型轉化,還可以使用非常炫的IOC和AOP等特性

C:說到這裡,現在"業界"有幾個類型轉化工作可以做到?我稍微看了一個現在非常流行的Automapper,自定義映射確實沒問題,但是映射過程還可以通過配置文件擴展或者IOC和AOP的我沒見識過,如果有人看到過請告知,我要好好學習學習

D:早期看過這篇文章的可能發現,變化很大,我把GlobalServices由靜態類修改可以實例化的形式,這樣就允許我們創建多套服務配置管理對象(使用子容器技術,繼承預設服務並覆蓋少數服務),進一步提高可擴展性

3、其實GlobalServices容器和其他容器還是有點區別的,繼續深挖源碼

這裡有一個不起眼的地方加了一行代碼,給GlobalServices容器”吃小竈“

不挖不知道,一挖嚇一跳,有一種”柳暗花明又一村“的感覺

哈哈,我就說我要對每個容器做包裝,”居心不良“吧;哈哈,這樣說太難聽了,一句話"還是為了更好的擴展"。

4、沒辦法了,還得繼續挖GlobalServices.CheckServices

這裡可以看到框架支持的"基本類型",把這些轉化策略都註冊到容器中,主要是擔心容器註冊的服務不夠用,把不足的基本類型轉化服務都註冊上

當然如果容器中已經存在同類型的"服務",這裡的註冊是會忽略的

同樣,就算是這裡註冊的服務,如果覺得不好用,也可以在外面重新註冊並覆蓋

還有一點,前面截圖可以明顯看出"基礎服務模塊"的基本樣子,但是除了”類型轉化子模塊“外,其他子模塊都還沒開發出來

 

四、擴展性演示

1、邏輯空(int轉bool)

前面有提高,我是把>0為true的,<=0為false,我一直用的很方便,我叫做"邏輯空",但是ms並不是這樣處理的,如果有的團隊還是希望按ms的規則怎麼辦,擴展啊

2、把上例中的註釋打開就切換為ms模式(==0為false)

上面的結果就是ms模式了

3、現在來看一下是怎麼擴展的

以上代碼很清楚,擴展很簡單,獲取服務配置的容器,註入服務並覆蓋原服務,就完成了擴展

 

暫時就挖到這裡,還遠沒有完全詮釋”類型轉化基礎服務“的可擴展性的全貌,但是該模塊還在測試和完善中,只好有空再補了

 


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

-Advertisement-
Play Games
更多相關文章
  • 介紹 本篇主要介紹Linux定時任務命令crontab的用法,crontab是定時任務的命令,而crond則是定時任務的啟動服務。crontab的定時任務分為系統任務和用戶任務,其實二者沒有太大的區別。 啟動 在Centos中crond服務預設是自動啟動的,如果沒有啟動可以手動啟動,具體方法如下。 ...
  • 情形: 1.主機(host):ubuntu 2.虛擬機里安裝的操作系統版本(guest):windows 7專業版 3.simplify3d破解版版本:3.0.2(破解需要的工具均在下文的百度雲地址里) 所需文件下載地址:http://pan.baidu.com/s/1slUoEZz,密碼:57cs ...
  • 在測試前,理應瞭解本機所具備的特點,比如CPU頻率、記憶體頻率、記憶體大小,等等信息。 查看CPU用如下命令(多少個核,頻率,特性等): cat /proc/cpuinfo 查看記憶體用如下命令:(只有當前記憶體大小,已用空間等等,不能看到記憶體頻率) cat /proc/meminfo 要查看記憶體型號和頻率 ...
  • 寫在前面 最近在重溫asp.net,找了一本相關的書籍。本書在第一章就講了,在不使用瀏覽器的情況下生成一個web請求,獲取伺服器返回的內容。於是在網上搜索關於Http請求相關的資料,發現了很多資料都是講述基於HttpGet和HttpPost請求伺服器的資源,然根據Get和Post的單詞意思就大概知道 ...
  • ...
  • 一、Association關聯關係 說明:Assocition(關聯):描述了兩個或多個類之間的結構性關係。 (1)普通關聯: 1)Association name名稱:用以描述該關係的性質。 2)Role角色:當一個類處於關聯的某一端時,該類就在這個關係中扮演了一個特定的角色;角色是關聯中靠近它的 ...
  • 今天要實現的是給PDF文件添加圖片背景這個功能。PDF是近年來最流行的文件之一,無論是辦公還是日常生活中都經常會用到,很多時候,PDF文件的背景色都是白色,看多了難免覺得累,更換PDF的背景不僅可以讓眼睛看起來更舒服,還可以讓PDF文件看上去更美觀。如何實現?作為一名程式猿,當然要親自“操刀上陣”, ...
  • 先在資料庫中建表: 再從後臺將表取出來,然後轉化為json格式,再將其執行ToString()操作後,賦值給前臺的隱藏域。 註意引用using Newtonsoft.Json; 前臺利用js將隱藏域中的值取出,由於這個值是字元串格式,需要將它轉為json格式。 利用eval來實現。 註意引用jQue ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...