C#
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C#
-
Section 4: Working with Data
-
Section 5: Error Handling
-
Section 6: Delegates and Events
-
Section 7: Async Programming
-
Section 8: More Language Features
-
Section 9: File I/O and Serialization
-
Section 10: Networking in .NET
-
Section 11: The .NET Ecosystem
-
Section 12: Memory and Performance
-
Section 13: Concurrency Beyond Async
-
Section 14: Reflection and Attributes
-
Section 15: Testing and Best Practices
-
Section 16: Design Patterns in C#
-
Section 17: Standard Library Deep Dive
-
Section 18: Data Structures and Algorithms in C#
-
Section 19: GUI and Desktop Development Overview
-
Section 20: Practical Projects
-
Section 21: More Practice Exercises
-
Section 22: More Standard Library and Text Processing
-
Section 23: More Design Patterns
-
Section 24: More Projects
-
Section 25: Interview Practice
-
Section 26: C# Keywords Reference (Modifiers)
-
Section 27: C# Keywords Reference (Statements)
-
Section 28: C# Keywords Reference (Operators)
-
Section 29: BCL: System.Collections.Generic
-
Section 30: BCL: System.Linq
-
Section 31: BCL: System.Threading
-
Section 32: BCL: System.IO
-
Section 33: BCL: System.Text and System.Text.Json
-
Section 34: BCL: System.Net.Http
-
Section 35: C# Language Specification Topics
-
Section 36: More Practice Exercises
-
Section 37: More Async Patterns
-
Section 38: More BCL: System.Reflection and System.Diagnostics
-
Section 39: Nullable Reference Types In Depth
-
Section 40: C# Records and Pattern Matching In Depth
-
Section 41: Dependency Injection Deep Dive
-
Section 42: More Interview and Whiteboard Practice
74: gRPC Basics in .NET
If you've spent most of your time building REST APIs, gRPC is going to feel like a bit of a culture shock. Instead of thinking in terms of "endpoints" and "HTTP verbs," we're thinking in terms of "services" and "remote procedures." It's essentially like calling a method on a class, but that class happens to live on a different server across the network.
The magic here is Protocol Buffers (Protobuf). Instead of sending bulky JSON strings back and forth, gRPC uses a binary format. It's faster, smaller, and—most importantly—it forces us to define a strict contract before we write a single line of C# code.
Defining the Inventory Contract
Let's build a simple Inventory Check service. Imagine a warehouse system where a storefront needs to quickly check if a specific item is in stock. I'll start by creating a inventory.proto file. This is the "source of truth" for both the server and the client.
syntax = "proto3";
option csharp_namespace = "InventoryService";
service Inventory {
rpc GetStockLevel (StockRequest) returns (StockResponse);
}
message StockRequest {
string sku = 1;
}
message StockResponse {
int32 quantity = 1;
bool is_available = 2;
}
Notice those numbers (= 1, = 2)? Those aren't values; they're field tags. Since the data is binary, gRPC doesn't send the name "sku" over the wire; it just sends the tag "1". This is why you can't just change these numbers once your service is in production—you'd break every client currently talking to your server.
Implementing the Server Logic
Once I save that proto file and build the project, .NET does some heavy lifting in the background. It generates a base class that I just need to inherit from. I don't have to worry about the networking guts; I just override the method and write the business logic.
public class InventoryProvider : Inventory.InventoryBase
{
private readonly Dictionary<string, int> _stock = new()
{
{ "LAPTOP-001", 15 },
{ "MOUSE-002", 0 },
{ "MONITOR-003", 7 }
};
public override Task<StockResponse> GetStockLevel(StockRequest request, ServerCallContext context)
{
_stock.TryGetValue(request.Sku, out int quantity);
return Task.FromResult(new StockResponse
{
Quantity = quantity,
IsAvailable = quantity > 0
});
}
}
Correcting a Common Proto Mistake
I'll be honest: when I first started with gRPC, I tried to be "efficient" and write my service definition like this: rpc GetStockLevel (string sku) returns (StockResponse);. I thought, "Why wrap a single string in a message object? That's just boilerplate."
The compiler immediately yelled at me. In gRPC, every request and response must be a defined message type. You cannot pass raw primitives like strings or ints directly into the RPC call. It feels tedious at first, but it's actually a lifesaver. If we ever need to add a "WarehouseId" or a "CustomerPriority" to that request later, we can do it without breaking the method signature for existing clients.
Wiring up the Client
Now that the server is running, the client side is surprisingly clean. I don't have to deal with HttpClient, JSON deserialization, or status code checks. I just create a channel and instantiate the generated client class.
using var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Inventory.InventoryClient(channel);
var response = await client.GetStockLevelAsync(new StockRequest { Sku = "LAPTOP-001" });
Console.WriteLine($"Quantity: {response.Quantity}, Available: {response.IsAvailable}");
I love how this feels. It's type-safe from end to end. If I change a field name in the proto file, the client code won't even compile until I fix the reference. That's a massive upgrade over the "fingers crossed" approach we often use with REST and JSON.
📋 Practical Task
Build a Product Pricing gRPC Service
Your task is to extend the concepts from this lesson by creating a new gRPC service that handles product pricing. Follow these requirements:
- Create a
pricing.protofile defining a service calledPriceCalculator. - The service should have a method
GetPricethat takes aPriceRequest(containing aproductIdand acurrencyCode) and returns aPriceResponse(containing theamountas a double and aformattedPricestring). - Implement the server-side logic in a class inheriting from the generated base class. Use a hard-coded dictionary to simulate a price database.
- Write a small console client that requests the price for a specific product and prints the
formattedPriceto the console.
There are no comments for now.