Posts
'gRPC - Create C# gRPC client'
要建立 gRPC 的 Client,須先將 GRPC.Tools、GRPC.Core、Google.Protobuf 這三個 NuGet 套件加入參考。
... <ItemGroup> <PackageReference Include="Google.Protobuf" Version="3.7.0" /> <PackageReference Include="Grpc.Core" Version="1.20.0" /> <PackageReference Include="Grpc.Tools" Version="1.20.0" /> </ItemGroup> ... 然後設定從 Proto 檔產生需要的程式部分。
<ItemGroup> <Protobuf Include="../../proto/*.proto" GrpcServices="Client" /> <Content Include="@(Protobuf)" LinkBase="" /> </ItemGroup> 編譯後可在 obj 下看到產出的檔案。
接著開始實作 Client。
然後帶入 Server 位置建立 Channel 物件。
... var channel = new Channel($"{host}:{port}", ChannelCredentials.Insecure); ... 接著帶入 Channel 建立 Service 的 Client 物件。
... var client = new HelloService.HelloServiceClient(channel); ... 透過 Service 的 Client 物件調用對應的方法。
read morePosts
'gRPC - Create C# gRPC server'
要建立 gRPC 的 Server,須先將 GRPC.Tools、GRPC.Core、Google.Protobuf 這三個 NuGet 套件加入參考。
... <ItemGroup> <PackageReference Include="Google.Protobuf" Version="3.7.0" /> <PackageReference Include="Grpc.Core" Version="1.20.0" /> <PackageReference Include="Grpc.Tools" Version="1.20.0" /> </ItemGroup> ... 然後設定從 Proto 檔產生需要的程式部分。
<ItemGroup> <Protobuf Include="../../proto/*.proto" GrpcServices="Server" /> <Content Include="@(Protobuf)" LinkBase="" /> </ItemGroup> 編譯後可在 obj 下看到產出的檔案。
接著開始實作 Service。
繼承產出的 Service 基底類別。
... public class HelloServiceImpl:HelloService.HelloServiceBase ... 並覆寫該服務的方法即可。
... public override Task<HelloResponse> SayHello(HelloRequest request, ServerCallContext context) { ... } ... 程式寫起來會像下面這樣 (這邊筆者只是簡單的將調用時送進來的人名做些加工回傳而已):
using System.Threading.Tasks; using Grpc.Core; public class HelloServiceImpl:HelloService.
read morePosts
gRPC - Protocol Buffers/gRPC Integration Into .NET Build
Grpc.Tools 在 1.17 後我們可以將 proto 檔的編譯動作直接整到 dotnet build。使用上只要在專案檔中加上 設定即可。
像是筆者這邊準備了一個 GRPC.Message 專案。加入 Grpc/Grpc.Tools/Google.Protobuf NuGet 套件參考。
proto 檔放在上上層的 proto 目錄下。
. |___ proto | |___ message.proto | |___ service.proto |___ src |___ GRPC.Message 那在 GRPC.Message 的專案檔中可以像下面這樣加入 設定,會用 Include 指定 proto 檔、ProtoRoot 指定 proto 檔中 import 語法的參考位置、OutputDir 指定輸出位置、GrpcService 指定要編譯 gRPC 的 server 還是 client…等。
... <ItemGroup> <Protobuf Include="../../**/*.proto" OutputDir="%(RelativePath)" CompileOutputs="false" GrpcService="both" /> </ItemGroup> ... 像是如果只要產生 Server 需要使用的類別就可以像這樣設定。
... <ItemGroup> <Protobuf Include="../../proto/*.proto" GrpcServices="Server" /> </ItemGroup> .
read morePosts
NSaga - Getting started
使用 NSaga 來做 Saga pattern,需先透過 NuGet 安裝 NSaga 套件。
PM> Install-Package NSaga 接著要定義 Transaction 中的每一個動作,也就是 NSaga 中的 Message。
這邊要注意 NSaga 必須特別定義 Transaction 中的第一個 Message,定義的方式就是造一個專屬的 Message Class,並實作 IInitiatingSagaMessage 介面。
public class StartSagaMessage: IInitiatingSagaMessage { public Guid CorrelationId { get; set; } } IInitiatingSagaMessage 介面只有一個屬性 CorrelationId,用來接 Transaction Id 用,可用來識別這次觸發的 Transaction。除了介面定義的屬性外,若是需要額外的資料也可以自己附加。
第一個 Message 定義完其它後面的 Message 定義方式就一樣了,只要造專屬的 Message Class,並實作 ISagaMessage 介面即可。
public class SagaMessage: ISagaMessage { public Guid CorrelationId { get; set; } } 接著要定義 Transaction 要儲存的資訊,簡單造個 Model 類別即可。
read morePosts
'C# 8.0 - Static local functions'
C# 8.0 開始支援靜態的 Local functions,只要直接在 Local functions 前面加掛 static 關鍵字即可。
using System; namespace StaticLocalFunctions { class Program { static void Main(string[] args) { static void SayHello(string name) => Console.WriteLine(string.Format("Hello~{0}", name)); //static void SayHello(string name) //{ // Console.WriteLine(string.Format("Hello~{0}", name)); //} SayHello("Larry"); } } } Static Local functions 在使用上跟一般的靜態方法一樣,需要使用的資料需從參數傳入,或是直接使用靜態的變數值,如果直使用 static Local functions 外的區域變數編譯器會報錯。
using System; namespace StaticLocalFunctions { class Program { static void Main(string[] args) { var name = "Larry"; static void SayHello() => Console.
read morePosts
'C# 8.0 - Indices and ranges'
C# 8.0 提供了 Index 與 Range。
要取得陣列指定位置的元素本來需要帶入 int 型態的索引位置到索引子,現在可改帶入 Index,Index 的數值表示寫法跟一般的整數數值類似,只是從尾部倒過來的索引可直接在前面加上 ^ 符號表示,像是最後一筆資料的索引位置可用 ^1 表示,比起以前自己要用陣列長度推算方便了許多。
... var lastData = data[^1]; ... 除了上面類似數值的表示方式外,也可以直接使用 Index 類別來撰寫。
... var firstData = data[Index.Start]; var secondData = data[Index.FromStart(1)]; //var secondData = data[new Index(1)]; var lastData = data[Index.FromEnd(1)]; //var secondData = data[new Index(1, true)]; ... 完整的範例會像下面這樣:
using System; using System.Linq; namespace Indices { class Program { static void Main(string[] args) { var data = Enumerable.Range(1, 5).ToArray(); //var firstData = data[0]; //var secondData = data[1]; //var lastData = data[^1]; var firstData = data[Index.
read morePosts
'C# 8.0 - Using declarations'
C# 8.0 以前使用 using 釋放物件,會在 using 後用小刮號包住要釋放的物件,然後在下面用大括號指示物件的生命週期範圍。
... using(var obj = new DisposableClass()) { ... } ... 程式寫起來會像下面這樣:
using System; namespace UsingDeclarations { class Program { static void Main(string[] args) { using (var obj = new DisposableClass()) { Console.WriteLine(obj.ToString()); } } } class DisposableClass : IDisposable { public void Dispose() { Console.WriteLine("Dispose..."); } } } C# 8.0 後支援 Using declarations,可以直接在變數宣告前面加掛 using 關鍵字,一樣可以達到物件釋放的效果。
... using var obj = new DisposableClass(); ... 程式寫起來會像下面這樣:
read morePosts
Azure - Create a function app from the Azure portal
使用 Azure portal 建立函數應用程式,要先選取建立資源。
在計算資源這邊找到函數應用程式。
輸入資源的名稱、資源群組、作業系統、主機位置、儲存體等資訊後按下建立按鈕。
建立完成後,所建立的函數應用程式可在資源群組中查閱。
Link Create a function app from the Azure portal
read morePosts
Photo Editor - Change photo size
要使用 Photo Editor 在 Android 上進行圖片大小的調整。
可先選取要處理的圖片,選取分享。
將圖片分享至 Photo Editor。
然後在 Photo Editor 下方找到變更尺寸按鈕。
透過下方的按鈕或是拖曳下方水平 bar 調整適當的尺寸,如果要輸入指定尺寸,可按下左下方畫有筆的按鈕輸入設定。
尺寸調整完按下右上方的勾勾按鈕確認圖片尺寸變更。
最後按下左上方的箭頭。
按下儲存。
將變更尺寸的圖片儲存起來。
read morePosts
Photo Editor - Clip photo
要使用 Photo Editor 在 Android 上進行圖片的裁切。
可先選取要處理的圖片,選取分享。
將圖片分享至 Photo Editor。
然後在 Photo Editor 下方找到裁切按鈕。
按下裁切按鈕後框出裁切後要留下來的部份,按下右上方的勾勾按鈕確認裁切。
圖片會被裁切成只剩下剛所框出的部份。
最後按下左上方的箭頭,儲存裁切的結果即可。
read more