A modern calculator implementation using gRPC for service communication in .NET 9.0. This project demonstrates how to build a distributed calculator service with client-server architecture using gRPC, containerized with Docker, and packaged as reusable NuGet and npm packages using Cake build system.
- Calculator.Server - gRPC server library and service implementation
- Calculator.Client - gRPC client library for consuming calculator services
- @calculator/web - Angular web client library for calculator services
-
Calculator.Server: gRPC server implementation with calculator operations
- Supports basic arithmetic operations (Add, Subtract, Multiply, Divide)
- Includes input validation and error handling
- Uses logging for operation tracking
- Containerized with Docker
- Supports gRPC-Web for browser compatibility
- Available as NuGet package
-
Calculator.Client: Console application that connects to the gRPC server
- Demonstrates how to make gRPC calls to the server
- Implements dependency injection for better service management
- Uses structured logging for operation tracking
- Handles server responses and errors
- Containerized with Docker
- Configurable server connection through environment variables
- Available as NuGet package
-
Calculator.Web: Angular web client application
- Modern web interface for the calculator service
- Two input fields for numbers
- Operation buttons (Add, Subtract, Multiply, Divide)
- Submit and Clear functionality
- Real-time result display with error handling
- Responsive design with clean UI
- Uses gRPC-Web to communicate with the server
- Available as npm package
-
Calculator.Tests: Unit tests for the calculator service
- Tests all arithmetic operations
- Includes edge cases and error scenarios
- Uses xUnit testing framework
-
Docker Support: Complete containerization
- Multi-stage builds for optimal image size
- Docker Compose for orchestration
- Isolated network for service communication
- Web client served via Nginx
This project uses Cake (C# Make) for cross-platform build automation:
- build.cake: Main build script with all build tasks
- build.ps1: PowerShell bootstrap script for Windows
- build.sh: Bash bootstrap script for Linux/macOS
- dotnet-tools.json: .NET tool configuration for Cake
# Build everything
dotnet cake --target=Build
# Run tests
dotnet cake --target=Test
# Create packages
dotnet cake --target=Pack
# Full CI pipeline (clean, build, test, pack)
dotnet cake --target=CI
# Publish packages to NuGet and npm
dotnet cake --target=Publish- Add Operation: Adds two numbers
- Subtract Operation: Subtracts two numbers
- Multiply Operation: Multiplies two numbers
- Divide Operation: Divides two numbers (includes division by zero validation)
- Web Interface: User-friendly Angular web application
- Real-time Validation: Input validation and error handling
- Responsive Design: Works on desktop and mobile devices
- Built with .NET 9.0
- Uses gRPC for service communication over HTTP/2
- gRPC-Web support for browser compatibility
- Angular 17 frontend with TypeScript
- Implements async/await pattern
- Implements Dependency Injection (DI) principles
- Includes comprehensive logging with Microsoft.Extensions.Logging
- Follows IoC principles for better maintainability and testing
- Includes proper error handling and logging
- Certificate generation tools for secure communication
- Follows C# and Angular best practices
-
Clone the repository:
git clone https://github.com/pskumar81/CalculatorGrpc.git
-
Build and run using Docker Compose:
docker-compose up --build
The services will be available at:
- gRPC Server: http://localhost:5001
- Web Client: http://localhost:4200
- Console Client: Automatically connects to the server through Docker network
-
Clone the repository:
git clone https://github.com/pskumar81/CalculatorGrpc.git
-
Build the solution:
dotnet build
-
Run the server:
cd Calculator.Server dotnet run -
Run the client (in a new terminal):
cd Calculator.Client dotnet run
dotnet add package Calculator.Serverusing Calculator.Server.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;
var builder = WebApplication.CreateBuilder(args);
// Add gRPC services
builder.Services.AddGrpc();
builder.Services.AddGrpcReflection();
// Configure Kestrel for HTTP/2
builder.Services.Configure<KestrelServerOptions>(options =>
{
options.ListenAnyIP(5001, o => o.Protocols = HttpProtocols.Http2);
});
var app = builder.Build();
// Configure gRPC pipeline
app.MapGrpcService<CalculatorService>();
app.MapGrpcReflectionService();
app.Run();dotnet add package Calculator.Clientusing Calculator.Client.Services;
using Grpc.Net.Client;
var services = new ServiceCollection();
services.AddCalculatorClient("https://localhost:5001");
var serviceProvider = services.BuildServiceProvider();
var calculatorClient = serviceProvider.GetRequiredService<ICalculatorClientService>();
var result = await calculatorClient.AddAsync(5, 3);
Console.WriteLine($"5 + 3 = {result}");npm install @calculator/webimport { CalculatorService } from '@calculator/web';
export class AppComponent {
constructor(private calculatorService: CalculatorService) {}
async calculate(a: number, b: number, operation: string) {
switch(operation) {
case 'add':
return await this.calculatorService.add(a, b);
case 'subtract':
return await this.calculatorService.subtract(a, b);
// ... other operations
}
}
}Add to your Angular module:
import { CalculatorModule } from '@calculator/web';
@NgModule({
imports: [
CalculatorModule.forRoot({
serverUrl: 'https://localhost:5001'
})
]
})
export class AppModule { }Run the tests using:
dotnet testThe application is fully containerized with Docker support:
- Multi-stage Docker builds for both client and server
- Docker Compose for easy deployment and service orchestration
- Configured for HTTP/2 communication
- Includes certificate generation tools for secure communication
The project includes tools for generating certificates for secure communication:
-
Navigate to the certs directory:
cd certs -
Run the certificate generation script:
./generate-certs.ps1
This will generate:
- CA certificate
- Server certificate
- Client certificate
These certificates can be used to enable mutual TLS (mTLS) for secure communication between the client and server.
- Multi-stage builds for both client and server
- Docker Compose for service orchestration
- Environment Variables for configuration
- Network Isolation between services
- Optimized Images using .NET runtime base images
Build and start the services:
docker-compose up --buildStop the services:
docker-compose down- Division by zero throws a proper gRPC exception
- All operations are logged for monitoring and debugging
- Client handles server errors gracefully
- Docker containerization ensures consistent environment
This project includes a comprehensive GitHub Actions CI/CD pipeline with the following features:
- CI/CD Pipeline: Builds, tests, and deploys on every push to master
- Pull Request Validation: Quick validation for PRs
- Code Quality Analysis: CodeQL security scanning and SonarCloud analysis
- Automated Releases: Version tagging and Docker image publishing
- Dependency Updates: Automated dependency updates via Dependabot
Docker images are automatically built and published to GitHub Container Registry:
ghcr.io/pskumar81/calculator-docker-calculator-serverghcr.io/pskumar81/calculator-docker-calculator-webghcr.io/pskumar81/calculator-docker-calculator-client
- CodeQL security analysis for C# and JavaScript
- Docker image vulnerability scanning with Trivy
- Dockerfile linting with Hadolint
- Automated dependency security updates
All workflow statuses are displayed via badges at the top of this README. For detailed information, see .github/WORKFLOWS.md.
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a new Pull Request