A Proof of Concept Web API built with .NET 9 and Hexagonal Architecture that integrates OpenRouter AI for document analysis. This application demonstrates how to build a scalable, testable, and maintainable AI-powered document processing system.
- .NET 9 SDK or later
- An API key from OpenRouter
- A text editor or IDE (VS Code, Visual Studio, JetBrains Rider)
-
Clone the repository:
git clone <repository-url> cd NetAI-POC
-
Restore dependencies:
dotnet restore
-
Build the solution:
dotnet build
-
Open
src/NetAI-POC.API/appsettings.json -
Add your OpenRouter API key in the
OpenRoutersection:{ "OpenRouter": { "ApiKey": "your-api-key-here" } }Alternatively, you can use environment variables:
export OPENROUTER_API_KEY="your-api-key-here"
dotnet run --project src/NetAI-POC.API- Open the solution file (
NetAI-POC.sln) in your IDE - Set
NetAI-POC.APIas the startup project - Press F5 or click the Run button
The API will start at http://localhost:5000 by default.
To run the unit tests:
dotnet testTo run tests with coverage:
dotnet test --collect:"XPlat Code Coverage"Once the application is running, you can access the Swagger documentation at:
http://localhost:5000/swagger
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/document-analysis/analyze |
Analyze a document using AI |
| GET | /api/document-analysis/models |
Get available AI models |
This project follows Hexagonal Architecture (also known as Ports and Adapters) with clear separation of concerns:
┌─────────────────────────────────────────────────────────────────┐
│ API Layer (Outer) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Controllers │ │
│ │ DocumentAnalysisController │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Application Layer │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Use Cases │ │
│ │ - AnalyzeDocumentHandler - GetAvailableModelsHandler │ │
│ │ Services │ │
│ │ - ModelSelectionService │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Domain Layer (Core) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Entities │ │
│ │ - Document - AnalysisResult - ModelInfo │ │
│ │ Value Objects │ │
│ │ - DocumentId - FileName - FileContent - ModelId │ │
│ │ Ports (Interfaces) │ │
│ │ - IDocumentAnalysisService - IAIProvider - IFileStorage│
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Infrastructure Layer │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Adapters │ │
│ │ - OpenRouterAdapter - FileStorageAdapter │ │
│ │ Services │ │
│ │ - DocumentAnalysisService │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
NetAI-POC/
├── src/
│ ├── NetAI-POC.API/ # Web API layer
│ │ ├── Controllers/
│ │ │ └── DocumentAnalysisController.cs
│ │ ├── Middleware/
│ │ │ └── ExceptionHandlingMiddleware.cs
│ │ ├── Program.cs
│ │ └── appsettings.json
│ │
│ ├── NetAI-POC.Application/ # Application layer
│ │ ├── DTOs/
│ │ │ ├── DocumentAnalysisRequestDto.cs
│ │ │ └── DocumentAnalysisResponseDto.cs
│ │ ├── UseCases/
│ │ │ ├── AnalyzeDocument/
│ │ │ │ ├── AnalyzeDocumentCommand.cs
│ │ │ │ └── AnalyzeDocumentHandler.cs
│ │ │ └── GetAvailableModels/
│ │ │ ├── GetAvailableModelsQuery.cs
│ │ │ └── GetAvailableModelsHandler.cs
│ │ └── Services/
│ │ └── ModelSelectionService.cs
│ │
│ ├── NetAI-POC.Domain/ # Domain layer (Core)
│ │ ├── Entities/
│ │ │ ├── Document.cs
│ │ │ ├── AnalysisResult.cs
│ │ │ └── ModelInfo.cs
│ │ ├── ValueObjects/
│ │ │ ├── DocumentId.cs
│ │ │ ├── AnalysisResultId.cs
│ │ │ ├── ModelId.cs
│ │ │ ├── FileName.cs
│ │ │ └── FileContent.cs
│ │ ├── Enums/
│ │ │ ├── FileType.cs
│ │ │ └── AnalysisType.cs
│ │ └── Ports/
│ │ ├── Incoming/
│ │ │ └── IDocumentAnalysisService.cs
│ │ └── Outgoing/
│ │ ├── IAIProvider.cs
│ │ └── IFileStorage.cs
│ │
│ └── NetAI-POC.Infrastructure/ # Infrastructure layer
│ ├── Adapters/
│ │ ├── OpenRouterAdapter.cs
│ │ └── FileStorageAdapter.cs
│ └── Services/
│ └── DocumentAnalysisService.cs
│
└── tests/
└── NetAI-POC.Tests/ # Unit tests
├── Domain/
│ ├── DocumentTests.cs
│ └── ValueObjectTests.cs
└──}