Asp.net 面向接口可扩展框架之类型转化基础服务
新框架正在逐步完善,可喜可賀的是基礎服務部分初具模樣了,給大家分享一下
由于基礎服務涉及面太廣,也沒開發(fā)完,這篇只介紹其中的類型轉(zhuǎn)化部分,命名為類型轉(zhuǎn)化基礎服務,其實就是基礎服務模塊的類型轉(zhuǎn)化子模塊
說到類型轉(zhuǎn)化必須要弄清楚.net的類型,類型都不清楚何來類型轉(zhuǎn)化
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并不含在內(nèi)
? ? ? ? ?有的同學可能說,別說那兩個了,里面就除了Char和Double其他都沒用過;老實說MS真的把.net程序員徹底慣壞了
? ? ? ? ?其實Boolean就是我們常用的bool,Int32就是int,Int64就是long,Single就是float
? ? ?1.4?Primitive類型有什么用呢?
? ? ? ? ?Primitive是基元類型,可以這樣理解,其他類型都是由Primitive類型構(gòu)成的或者衍生的,.net對Primitive支持最好,"有些地方"對于非Primitive類型支持不好,可能造成"靈異"事件(對于一般的項目是很難碰到的,如果你能碰到,說明你對.net鉆研的比較深了,普通的工程師就更不要嚷嚷說.net類型有缺陷不敢用之說,最多底層框架開發(fā)者或者架構(gòu)師小心一點)
這里就不展開了
2、IConvertible類型
IConvertible并不是新維度的類型類別,IConvertible是MS定義的一個接口,我這里講的IConvertible類型特指Ms定義的基本類型中繼承了該接口的類型
我來稍作解析一下,繼承了IConvertible的類型非常強大,可以方便的轉(zhuǎn)化為常用的這15種類型,也正是這15種類型繼承了IConvertible接口
也就是這15種類型可以方便的相互轉(zhuǎn)化(其實不一定的,有些轉(zhuǎn)化是會出錯的)
? ? ?IConvertible類型轉(zhuǎn)化具有高度的擴展性,可以傳一個格式化的參數(shù)(IFormatProvider)
? ? ?
?3、"基本"類型
? ? ?這里是我定義的”基本類型“,我認為有這些類型就足夠開發(fā)使用,框架對此之外的類型不予"支持",或者這些類型優(yōu)先支持
? ? ?包含類型列表:bool、byte、char、decimal、double、float、int、long、string、DateTime、byte[]
? ? ?注1:在現(xiàn)在內(nèi)存這么便宜的時代,我認為短數(shù)據(jù)類型的作用不大,短數(shù)據(jù)類型都使用int就好了
? ? ?注2:我也不喜歡使用無符號類型,所以又省略了一大批類型,對于數(shù)字類型Ms使用==0表示"邏輯空",我使用<=0表示"邏輯空",后面還有相關例子
? ? ?注3:這樣做也是情非得已,類型太多了,其排列組合更多,好在本框架是可擴展框架,使用本框架的時候可以自己擴展支持的類型,當然也可以開發(fā)一個類型擴展的組件(類庫),需要的時候自己注冊進去
?現(xiàn)在開始演示類型轉(zhuǎn)化基礎服務
一、類型太多,這里先拿int類型測試
1、字符串轉(zhuǎn)int
2、不同數(shù)字類型轉(zhuǎn)化為Int
這里我要多嘮叨一句,我前面說過對”基本類型“以外的不予支持,其實是不"支持"轉(zhuǎn)化為這些類型,這些類型轉(zhuǎn)化為”基本類型“是沒有問題的
另外,會嘗試IConvertible的類型相互轉(zhuǎn)化,如果Ms支持的很好的IConvertible轉(zhuǎn)化.這里也沒道理不支持的
3、object轉(zhuǎn)化為int
以上例子可以看出,基本類型轉(zhuǎn)化完全沒有問題,其實在主框架,我也不打算默認實現(xiàn)復雜自定義類型的轉(zhuǎn)化,這個留給擴展實現(xiàn)
有人可能會說你上面的這些功能So easy,實現(xiàn)過類似功能的多如牛毛,不過是多造個輪子而已。確實,基本類型轉(zhuǎn)化實現(xiàn)簡單,但是這里要強調(diào),我做的是可擴展框架,可擴展是亮點,而且非常容易擴展
二、擴展自定義類型轉(zhuǎn)化為int的例子
1、先看自定義類型代碼
非常簡單還是解讀一下,定義了兩個類型,customObj明顯是個模型(Model)類,customConverter有一個方法傳入一個customObj對象返回一個int值
2、再看對象轉(zhuǎn)化代碼
首先我們看結(jié)果,是我們預期的效果,和customConverter的Get方法的效果一致,但是我們沒有直接調(diào)用customConverter.Get,甚至好像和customConverter類型都沒什么關系
這里有幾個關鍵因素,其一是GlobalServices.Convert方法是怎么運行的;其二是GlobalServices.CreateContainer()是什么鬼
?
三、源碼解析
1、GlobalServices.Convert方法解析
這個類型轉(zhuǎn)化還是挺復雜的,挑主要的來解讀
1.1?TryConvert是嘗試類型轉(zhuǎn)化,如果轉(zhuǎn)化失敗可以換一種方法再做
這種方式在本框架中有大量應用,其實就就形成一個”策略鏈“,每個”策略“判斷一個這個問題自己是否是自己可以處理的類型,不能處理,下一個策略繼續(xù),這樣非常便于擴展
在TryConvert中先調(diào)用個接口IEntityConvert,轉(zhuǎn)化失敗再調(diào)用IEntityAccess用來轉(zhuǎn)化
這里有一個特別重要的事情,就是這個接口的對象從哪里來,這里是來自一個容器對象,這里很清楚的看到本框架的一個擴展點,只要往容器里面添加"策略"就可以增強本框架的類型轉(zhuǎn)化功能,這是我為什么說主框架不打算實現(xiàn)復雜的類型轉(zhuǎn)化,真的非常容易擴展
1.2 再看Convert主方法
A:先按當前類型嘗試轉(zhuǎn)化
? ? ?如果策略庫(容器注冊)里面有當前兩種類型轉(zhuǎn)化的策略,性能是最好的,優(yōu)先執(zhí)行
B:轉(zhuǎn)化失敗判斷當前對象是否為空
對象為null,放棄轉(zhuǎn)化,直接返回默認值
C:Transform.TryConvertByType
這個簡單就是強制類型轉(zhuǎn)化,如果T是S的基類,這個時候就可以直接轉(zhuǎn)化過去,也是非常安全的?
D:再嘗試IConvertible轉(zhuǎn)化
? ? 前面說到系統(tǒng)的IConvertible定義了15種基本類型的相互排列組合轉(zhuǎn)化,而且還可以使用IFormatProvider自定義轉(zhuǎn)化,這就是一個強大的轉(zhuǎn)化機器,不能不試
E:再檢測返回類型是否為string,如果是string直接調(diào)用對象的ToString()
F:最后嘗試把s對象轉(zhuǎn)化為字符串,然后把字符串轉(zhuǎn)化為目標類型(T)對象
? ?其實這里把字符串作為基本數(shù)據(jù)格式,相當于與對s對象序列化為字符串,然后把字符串反序列化為T類型對象,也不怪我怎么用,.net所有類型都有一個ToString()方法,所以string是個不錯的中間類型
功能是不是非常強大,也非常有別于很多類型轉(zhuǎn)化工具,上來先反射,獲取類型元數(shù)據(jù),然后調(diào)用屬性和字段,現(xiàn)在還沒做測試,我這種方式可能會有明顯的性能優(yōu)勢,但是性能現(xiàn)在不是我最想考慮的問題,我現(xiàn)在考慮的是怎么可以非常簡單的擴展
2、GlobalServices.CreateContainer()是什么鬼
CreateContainer定義
A:從上面可以看出GlobalServices.CreateContainer就是一個再普通不過的容器,默認實例的容器名是GlobalServices
B:前面有提到容器是可以擴展的,只要我們使用的容器支持(比如Unity、Spring.net等),我們完全可以使用配置文件來擴展類型轉(zhuǎn)化,還可以使用非常炫的IOC和AOP等特性
C:說到這里,現(xiàn)在"業(yè)界"有幾個類型轉(zhuǎn)化工作可以做到?我稍微看了一個現(xiàn)在非常流行的Automapper,自定義映射確實沒問題,但是映射過程還可以通過配置文件擴展或者IOC和AOP的我沒見識過,如果有人看到過請告知,我要好好學習學習
D:早期看過這篇文章的可能發(fā)現(xiàn),變化很大,我把GlobalServices由靜態(tài)類修改可以實例化的形式,這樣就允許我們創(chuàng)建多套服務配置管理對象(使用子容器技術(shù),繼承默認服務并覆蓋少數(shù)服務),進一步提高可擴展性
3、其實GlobalServices容器和其他容器還是有點區(qū)別的,繼續(xù)深挖源碼
這里有一個不起眼的地方加了一行代碼,給GlobalServices容器”吃小灶“
不挖不知道,一挖嚇一跳,有一種”柳暗花明又一村“的感覺
哈哈,我就說我要對每個容器做包裝,”居心不良“吧;哈哈,這樣說太難聽了,一句話"還是為了更好的擴展"。
4、沒辦法了,還得繼續(xù)挖GlobalServices.CheckServices
這里可以看到框架支持的"基本類型",把這些轉(zhuǎn)化策略都注冊到容器中,主要是擔心容器注冊的服務不夠用,把不足的基本類型轉(zhuǎn)化服務都注冊上
當然如果容器中已經(jīng)存在同類型的"服務",這里的注冊是會忽略的
同樣,就算是這里注冊的服務,如果覺得不好用,也可以在外面重新注冊并覆蓋
還有一點,前面截圖可以明顯看出"基礎服務模塊"的基本樣子,但是除了”類型轉(zhuǎn)化子模塊“外,其他子模塊都還沒開發(fā)出來
暫時就挖到這里,還遠沒有完全詮釋”類型轉(zhuǎn)化基礎服務“的可擴展性的全貌,但是該模塊還在測試和完善中,只好有空再補了
相關文章
Asp.net 面向接口框架之應用程序上下文作用域組件
Asp.net 面向接口可擴展框架之核心容器
原文地址:http://www.cnblogs.com/xiangji/p/5440373.html
.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注
贊賞
人贊賞
總結(jié)
以上是生活随笔為你收集整理的Asp.net 面向接口可扩展框架之类型转化基础服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用VS Code开发 调试.NET C
- 下一篇: 玩玩Xamarin Evolve 201