發表文章

目前顯示的是 10月, 2020的文章

使用IoC與DI有何意義? (三) 在 Console 程式中使用DI

圖片
這一篇的重點在介紹,如何在Console App中使用DI,但我們的重點卻不是 Console,而是 “使用DI”。 看完 前面 兩篇,你應該要想到一個問題,如果PageModel或MVC的Controller,被呼叫的時候,.net core的DI服務會自動幫我們把Startup.cs中指定好的類別實作,自動注入PageModel(或Controller),那Console中的Main()也會嗎? 好比說,如果我把程式寫成底下這樣: 我在Main()中能夠讀到 _SalaryFormula 的值嗎? 猜猜看? … … … 答案是===> 不會。 原因很簡單,因為Console App的進入點是靜態的 Main()函式,它根本就是一切的源頭,是應用程式被Launch起來的時候,最最最開始的入口,根本 不會有人去幫你 run 上面 5-8行的建構子,所以理所當然的也沒有注入這回事。 那…為何 PageModel可以? 為何MVC的Controller可以? 原因也不難,因為當用戶點選(或連結到)某一個頁面(或某一個Routing)的時候,該頁面(PageModel或Controller)所觸發的那隻程式(Onget() 或 Action),根本就不是整個程式的進入點。它(頁面)是"被"人家執行的。這個執行者不是用戶,是由 asp.net 的框架本身host的。 其實,整個 .net 應用程式的入口一直都是 Program.cs。 請看底下這個MVC Web應用程式的Program.cs: 事實上,Program.cs才是一切程式的進入點,而上面的Host,則是幫我們運行(Launch)起 asp,net web應用程式的背後推手。(未來有空我們再談這個類別) 一直以來,是有一個host幫我們承載每一個頁面的。當asp.net的某個頁面被呼叫,每一個controller被觸發,都不是該class被用戶主動觸發,而是『被』呼叫,被誰呼叫呢? 就是框架本身。正確的流程應該是,某個頁面(或說網址)被呼叫到時,asp.net框架中的底層(middleware, routing…etc.)得知該request,接收該http request的各種參數之後,幫我們new出我們所寫的程式碼(類別),然後把相關參數(像是Que

使用IoC與DI有何意義? (二) asp.net core中的DI服務

圖片
看過了 前面 的介紹,在瞭解了DI的背景需求與前提,以及採用介面來降低對特定物件實作的相依性之後,我們接著來看,怎麼使用asp.net core中的DI服務進行功能抽換。 事實上,早在約莫十年前,坊間就有很多DI框架或套件,例如我之前上課介紹過的Unity Application Block,他是一組DI Container(容器)套件,可以幫助我們更輕易地實現動態注入。而asp.net core則是把DI設計為服務,讓我們在程式碼當中,也可以輕易享有相關的功能。 在軟體開發的領域當中,你慢慢會發現到,真正困擾你的不是寫(新)程式,而是改(舊)程式。在我們開發系統的過程當中,我們會希望盡可能維持原始程式碼的不改變,就能夠加入新功能。原因很簡單,拿 先前 提過的例子,你只是想要修改薪資計算公式,而不是換掉整套HR系統,然後你剛才接手這個系統不久,這時候你不會想看完這套HR系統的整套原始程式碼,才能增加一個小小的薪資計算公式。 另外,你很有可能碰到運氣更差的狀況,就是你手邊根本沒有原始程式碼。 你不過就只是想改一下薪資計算的公式啊?(因為政府剛調整了最低薪資…) 記得Martin Fowler在 重構 一書中說過這麼一段話: 你回頭想,果真是如此,如果程式碼寫得夠好,你根本不需要看完所有程式碼,甚至也無須擁有整套程式碼,就能夠依照需求在系統中添加新功能。 所幸, 前面 我們已經為動態注入奠定好了基礎,請看底下這個Razor Page頁面: (我們之所以從 前面 的Console App改用Razor Page,是為了要展示asp.net core中的DI之故,請務必看過 前面這篇 才能理解底下情境) 上面這個頁面是 .net core 的 Razor Page Model,如果你不熟這個架構,只會MVC,那你就暫時把它當作某個Controller來看好了,後面我們會介紹Console和MVC模式下的DI。 它的執行結果如下: 頁面被載入的時候,會運行到OnGet()方法,其中的程式碼計算出的薪資是 28800,問題來了,OnGet(…)程式碼當中沒有看到誰去new了那個計算薪資的 _SalaryFormula 類別啊? 那這個實行個體是哪裡來的? 莫非是從建構子(上面程式碼第4行)傳入的? 是的,你猜對了。 整個asp.net core框架都支援套DI服務,不管是Web

雲端好物 - 用 Azure Files 建立隨處可存取的 D 槽...

圖片
雲端好物 - 用 Azure Files 建立隨處可存取的 D 槽... USB隨身碟不夠大? 擔心檔案遺失? 想要有便宜好用的儲存空間? 不如把檔案放上雲端吧。想把檔案放到雲端最簡單的方法,大概莫過於 Azure Files了。 當你設定好 Azure Files之後,等同於有一個雲端的隨身碟,不管在任何地方,只要你想要存取檔案,都可以透過安全的連線方式,取得位於雲端大儲存空間的檔案。 設定的方式很簡單,只要你建立好一個 Azure Storage Account,然後找到 檔案共用: 接著,依照下圖的方式,建立一個檔案共用: 建立完成後,選擇連接: 接著會出現底下畫面: 你會看到各種平台連結此雲端硬碟的方式,我們可以選擇某一個磁碟機號,例如上圖選擇W,選擇好後,複製上面這串script,到Windows的PowerShell環境執行: 最後會出現底下畫面: 當啷,一個W槽就出現了。 你可以使用這個 W 槽如同一般的資料夾一樣,所有的檔案也都能在雲端看到: 所有放上去的資料,由於Azure Storage本身就有備份與備援機制,檔案遺失的可能性幾乎等於0,你還可以隨時建立快照集(上圖A),輕而易舉的就讓檔案存取既安全又方便,從此之後檔案隨手可得。 備註:當然,這一切…網路速度要夠快才可以。

使用IoC與DI(Dependency Injection)有何意義? (一) 它到底是甚麼?

圖片
其實我們在好幾年前,就已經談過DI(Dependency Injection)這個主題。當時這類議題被視為進階的開發概念,但如果你最近開始使用 .net core,大概已經發現DI如今已變成.net core中的基本要求。 事實上,從事教育訓練這麼多年的觀察下來,不難發現其實還是有相當多的開發人員不真的很明白,到底DI對於軟體開發有何意義? 它能帶來什麼價值? 這一篇希望能夠用一個較為具體的實例,對初學者解釋到底什麼是DI,以及它能帶來的效益。 結論 先說結論,對開發人員來說,使用DI能夠帶來 提高 可測試性(testability) 以及 提高 可擴充性 的價值,同時降低相依性,讓程式碼便於維護。 在 asp.net core當中DI如今已是基本方案,asp.net core 是以 服務(DI Services) 的形式把DI這個機制實現在框架當中。讓開發人員不管是用 razor page, MVC, 或是其他開發方式,都可以(幾乎是必須)採用DI服務。 我們很久以前就說過,『框架』本身其實就是一種限制、一種引導,誘導開發人員往某一種方向去開發程式。而如今 asp.net core 把DI納作框架的一部分,就是在引導開發人員在開發時走向某一個路線。 什麼路線呢? 就是高可測試性、低耦合以及高可擴充性,如果兩相比較,我覺得asp.net core中的DI可以為開發人員實現高可測試性這個目的的可能性大概會更高一些,估計是因為最近幾年,unit test已經成為開發領域的某種潮流。 什麼是物件相依性 但不管如何,.net core已經把DI視為基礎,而你要理解這一切,得先搞清楚什麼是物件的相依性。 我常在上架構設計課程時說,職責分離這個設計概念很容易理解,誰都知道不同職責的模塊或物件就該分離,問題是怎麼決定誰的職責是甚麼? 到底誰又該跟誰分離? 等到有一天你真的開始設計,就會發現理解是一回事,真的明白到能夠動手設計又是另一回事… 看個例子,我們先來了解一下背景需求。 假設,我們打算為企業建構一個薪資計算的功能,已知薪資計算會依據三個參數,分別是本月上班時數(WorkHours),時薪(HourlyWage),以及請假時數(PrivateDayOffHours)。 也就是說,倘若Eric本月上班 19天,每天8小時,時薪200,本月請假1天,每請假一天倒扣200元,則E

千呼萬喚始出來:動態修改LINE Bot WebHook 的 API

圖片
很多人期待這組API很久了,終於,在光輝的十月,LINE通知大家,這組API出現了😍: https://developers.line.biz/en/news/2020/10/06/messaging-api-update-october-2020/ 過去,開發者要動態修改LINE Bot的WebHook是不可能的。😢 唯一的方式是去LINE的Developer後台 手動 修改。 但這造成了許多LINE Bot開發廠商的維運難度。 想像一下,你需要為近百個客戶同時升級改版,更新WebHook的時候,會是一個多大的工程? 😒 還不僅如此,有許多LINE Bot應用廠商,自己也做了LINE Bot的管理後台,想讓客戶輸入LINE Bot的Channel Access Token,就可以幫客戶的LINE Bot動態賦予不同的行為。但過去,這也無法達成,非得要到客戶的後台去設定不可。(但直接去客戶後台修改? 還是手動? 有點 low 了吧…) 而現在這一組API,則徹底的解決了這個問題。現在,你只要有LINE Bot的Channel Access Token,就可以動態幫LINE Bot隨時設定或調整WebHook URL。 LINE公布了這組API之後,我們的SDK當然立刻更新。 現在,你只需要透過底下這樣的指令,就可以動態設定 LINE Bot的WebHook: isRock . LineBot . Utility . SetWebhookEndpointURL ( ChannelAccessToken , WebHookUrl ) ; 想要抓取當前LINE Bot的WebHook也不是難事: var ret = isRock . LineBot . Utility . GetWebhookEndpointInformation ( ChannelAccessToken ) ; 上面取得的ret,會有底下2個屬性: active屬性可以得知當前是否有使用WebHook,而endpoint當然就是WebHook的url囉。 想要測試 WebHook是否正確也可以用 API呢,例如: ret2 = isRock . LineBot . Utility . TestWebhookEndpoint ( Chan