發表文章

目前顯示的是有「dotnet Core」標籤的文章

使用IoC與DI有何意義? (五) 透過設定實現注入

圖片
這一篇文章,照說應該接在之前寫過的 這篇 之後。但沒想到是,上一篇已經是 2020年的事情! 這連載也間隔太久了,哈。 在理解了DI的原理,並且知道注入的做法之後,我們繼續往下看,如果要動態實踐注入,該如何進行? 先前我們看到的程式碼中的注入,都是修改 program.cs 中的 AddTransient 來進行的,例如: serviceCollection . AddTransient < ISalaryFormula , SalaryFormula > ( ) ; 但如果我們想對 ISalaryFormula 這個介面,動態注入實作的類別,但不想改程式碼,可以怎麼做呢? 沒什麼複雜的,就是使用設定檔 appSettings.json,例如,我們可以建立這樣的配置: { "MyServiceConfig": { "MyServiceType": "consoleDI.SalaryFormula" } } 其中以字串描述了一個類別的路徑(NameSpace.ClassName),例如: “consoleDI.SalaryFormula” 如果要額外描述在哪一個組件(.dll)內,路徑則是 “NameSpace.ClassName, DllName” 有了設定之後,我們在主程式中,加入讀取該設定的程式碼(底下7-12行): public class Program { //這裡才是真正的進入點 main static void Main ( string [ ] args ) { //讀取appsettings.json中的設定,決定用哪一個類別實作 IConfiguration config = new ConfigurationBuilder ( ) . SetBasePath ( Directory . GetCurrentDirectory ( ) ) . AddJsonFile ( "appsettings.json" , optional : false ) ...

使用IoC與DI有何意義? (四) 使用IoC與DI提高可測試性

圖片
這一系列的文章,持續維持著一年更新一篇的進度,😛。 今天適逢良辰吉日,我們再次來談談,如何透過IoC與DI增加系統的可測試性。 關於單元測試(Unit Test) 我們知道,有單元測試的存在,我們得以放膽的修改程式碼,無須擔心程式碼的頻繁異動將造成意料之外的副作用。 也因此,有一些團隊追求著程式碼單元測試的覆蓋率。 然而,高覆蓋率的單元測試並不意味著就會有更高品質的程式碼,反而真正重要的是,如何為我們系統中的核心邏輯、重要的核心函式,適當的添加單元測試。 所以,我們接下來要來談一談,如何透過IoC與DI增加程式碼的可測試性。 關於可測試性 你大概也已經知道,我們可以透過Visual Studio為特定的method來建立單元測試。特別是重要的商業邏輯運算函式、或是API,都是單元測試非常能發揮功能的好對象。 然而,你可能會發現有些程式碼似乎難以測試,例如底下這個例子: Console.Write("請輸入金額(USD):"); var amount = int.Parse(Console.ReadLine()); //100 Console.Write("請輸入人數:"); var people = int.Parse(Console.ReadLine()); //5 Financy f = new Financy(); var CostByPeople = f.SplitMoney(amount, people); Console.Write(CostByPeople); 上面這段程式碼看起來簡單,實際上,也真的很簡單😎。 SplitMoney()是一個計算旅遊消費金額分攤的函式。 假設,你和一夥人出國旅遊,在路邊店家吃了一餐,總共100美元,你想計算每個人要負擔多少台幣,就可以使用這個函式。呼叫SplitMoney()時,傳入『美金總金額』和『人數』兩個參數,它就幫你算出一個人要付的台幣金額。 假設我們要針對這個函式進行單元測試,乍看之下似乎並不難,但我們看SplitMoney()的具體內容: public class Financy { public double SplitMoney(double USDAmount, int People) { var currenc...

使用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...

使用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...

使用 .net core 開發 LINE Bot(02) - 建立你的第一支LINE Bot(2020年版)

圖片
申請你的LINE Bot帳號 關於這個主題,我大概每年重寫一次,原因很簡單 – LINE的網站一直在變。 在敏捷成為主流的這個年代,網站改版已經是常態。有時候上課上到一半,突然間網站UI整個不同,也不是一件新奇的事情了。也因此,每年寫一版『申請帳號』流程,大概也是剛好而已。 來吧,如何申請你的LINE Bot帳號? 首先,請準備你的LINE帳號,我知道你有一個LINE ID,但我們用不上它,們待會需要的是你的email和密碼,也就是你用來登入desktop版本的LINE時,所用的那組email帳號和密碼,如果你真的沒有(不曾用PC/MAC登入LINE?) 那你待會用手機掃QR Code登入也行。 準備好帳密或手機之後,請進入底下網址: https://developers.line.biz/zh-hant/ 進入後,請點選下圖中的Log in,以你的帳號密碼登入: 如果出現底下畫面,請選擇 使用LINE帳號登入 接著,你可以輸入email和密碼,或是透過手機掃描QR Code登入: 第一次登入,可能會要求你建立Provider,這個Provider是你待會要建立的LINE Bot的所屬單位,一般用公司或機構名稱,如果你是自己玩玩,也可以用個人工作室名稱或你自己的代號: 建立完成之後,你可以在Provider的首頁,建立LINE Bot了。LINE Bot屬於 channel 的一種,所以你可以透過底下『Create a new channel』來建立: 接著在出現的畫面點選『Messaging API』,這就是LINE Bot帳號了: 接著在Create a channel的畫面中,選擇Bot的圖示(Channel Icon): 並填寫名稱(Channel name)、說明(Channel description)、分類和子分類(Category/Subcategory),並填寫你的mail和勾選同意條款後,按下Create即可: 取得重要資訊 建立好LINE Bot之後,我們要取得幾個重要的相關資訊,你可以在LINE Bot的首頁找到Messaging API,點選後,可以看到底下畫面: 即便你是該LINE Bot的建立者,你自己也要將其加入為好友才行測試。 透過上面的QR Code或Bot ID(@xxxxx...

在VS Code中發佈.net core網站到Azure Web App

圖片
自從開始用VS Code之後,過去在Visual Studio上的一些行為,也逐漸希望在VS Code當中一樣可以實現,最主要的當然是為了實踐跨平台,讓非windows用戶,也可以順暢的使用並參考我們所撰寫的文件和教學素材。 最近在寫 .net core Web範例,所以當然需要把寫好的.net code網站範例透過VS Code發佈到Azure WebApp上,CI環境用慣了,正當準備從Client端的VS Code發佈時,突然一愣,ㄟ…用VS Code怎麼發佈啊。 VS Code沒有像是Visual Studio那樣的發佈選單啊…找了一下,發現需要安裝Azure App Services擴充套件: 安裝後,你可以在command line透過 dotnet build; dotnet publish指令,把.net core應用建置封裝: 然後你可以在輸出資料夾中,看到publish目錄,你在該目錄上按下滑鼠右鍵,就會發現Deploy to Web App功能出現了: 後面就容易了,點選後會出現Sign in Azure引導你登入Azure: 登入成功後可以選擇你的訂閱帳戶: 再來可以選擇該訂閱帳戶下的WebApp(或新增): 後面就自動幫你發佈上去囉: 哈,其實還蠻簡單的嘛… ----------- 線上課程: https://www.udemy.com/line-bot/ 最新實體課程: http://www.studyhost.tw/NewCourses/LineBot 電子書: http://studyhost.blogspot.tw/2017/12/line-bot.html 實體書: https://www.tenlong.com.tw/products/9789865022662?list_name=srh LineBotSDK: https://www.nuget.org/packages/LineBotSDK 如果需要即時取得更多相關訊息,可按 這裡 加入FB專頁。若這篇文章對您有所幫助,請幫我們分享出去,謝謝您的支持。

用C#開發 LINE Bot (34) - 以.net core控制LINE Bot發送Push訊息

圖片
接續著 上一篇 介紹如何用 .net core的WebAPI來建立 LINE Bot WebHook,這一篇我們介紹如何使用 .net core的 razor page web app來建立發送(push)訊息的LINE Bot。 請先確定你使用的是.net core 3.0以上(建議3.1)的版本: 接著透過『dotnet new webapp -n test01』指令,來建立一個新的WebApp: 建立完成之後,別忘了先透過CD test01指令切到專案所在的資料夾,然後我們用底下指令,來安裝幾個套件: dotnet add package isrock.web.core.razor 執行結果如下: 接著是重要的步驟,請利用底下指令,安裝我們在nuget上的linebot範本: dotnet new --install isRock.Template.LineBotPush 成功執行之後,請繼續執行底下指令: dotnet new LineBotPush 你會看到該範本的程式碼已經加入我們專案中了,接著,我們用 『code .  』指令來開啟vs code: 你會看到專案中已經有我們寫好的範例程式碼。現在已經可以執行了。 請在VS Code的終端機中,用dotnet run執行這個WebApp: 開始運行之後,你就可以在瀏覽器中,以 https://localhost:5001/__samplelinebot 網址來執行該頁面: 您可以在上面這個頁面中,輸入channel access token, user id…等資訊,當然還有要傳送的訊息,按下Push即可發送訊息。 程式碼相當簡單: 詳細的操作影片可以參考底下: ----------- 線上課程: https://www.udemy.com/line-bot/ 最新實體課程: http://www.studyhost.tw/NewCourses/LineBot 電子書: http://studyhost.blogspot.tw/2017/12/line-bot.html   實體書: https://www.tenlong.com.tw/products/9789865022662?list_name=srh LineBotSDK: https://www.nuget.org/pa...

使用C#開發LINE Bot(32) – .net core 2.2 WebHook 範例

圖片
前面 我們談過了如何在 .ner core環境上透過 LineBotSDK發送訊息。我們今天來看如何建立一個WebHook… 我們先看執行結果: 當你跟bot說hello的時候,他會echo你hello,當你說 /show ButtonTempalte的時候,他會reply一個tempalte訊息,當你傳送貼圖的時候,它會回你一個貼圖。 我們來看WebHook的程式碼: 剛才我們說到依照用戶傳來的訊息,回覆相對的訊息的部分,是在27-78行,其中回覆文字訊息的部分是29-57行。你會看到我們在程式碼當中,透過bot物件採用ReplyToken回覆訊息。 回覆多則訊息 比較值得注意的地方是,我們回覆訊息的程式碼其實統一寫在76行,回覆的物件是responseMsgs,這是一個訊息的集合。裡面至多可以放5則訊息。而前面程式碼當中的判斷與回覆,其實只是把準備要回覆的訊息加入這個responseMsgs物件中。這樣的寫法比較理想,因為依照LINE的規格,ReplyToken只能使用一次,如此做法可以在程式碼的單一地方一次性的處理回覆,比較好管理,不容易發生replyToken使用多次的錯誤。 另外,程式碼最上面的5,6兩行,是從json檔案中取得appSetting,這是.net core新的做法,請讀者測是這個範例時,也要記得開啟appsettings.json置換當中的token與admin user ID: 程式碼的18-23行,其實就是取得LINE傳來的http body,並且透過我們的SDK Parsing成為ReceivedMessage物件,其中就包含了用戶跟我們LINE Bot對談傳來的訊息,後面25行LineEvent的操作我覺得我們的讀者應該就不陌生了。 小結 總的來說,使用.net core開發LINE Bot現在已經相對算是成熟很多了,我們的SDK目前也已經全面支援,不管是發送(push)/回覆(reply)文字或template訊息基本上都沒有甚麼問題。 而整段程式碼與過去最大的不同之處,大概只有取得config環境變數的作法稍有不同,完整的程式碼已經在 Github 上等你,請直接clone或fork下來使用即可,不用客氣。 如果你要測試,無須安裝VS 2019,使用MAC+VS Code開發也是很好的選擇,參考 前面 介紹過的做法,透過dotn...