AspireIfus is a reference implementation that demonstrates a Blazor WebApp front-end and a separate API service with light AI integration (chat + semantic search) and vector-store support.
This repository contains the following projects:
AspireIfus_ApiService- Minimal API that exposes project data endpoints, integrates with a SQL Server database via Dapper, and provides AI features (chat support + semantic/embedding search) using OpenAI-compatible models and a Qdrant vector collection.AspireIfus.WebApp- Blazor Interactive Server application that consumes the API and displays project lists and funding details. Uses a small typedProjectApiClientfor API calls.AspireIfus.AppHost- (Lightweight host project / shared defaults used by the services)AspireIfus.ServiceDefaults- Project-level helpers and registration extensions.
#Architectural Overview & Design Rationale
This project is a small reference implementation exploring how AI-augmented search patterns (semantic/embedding search) can sit alongside traditional database-backed search in a clean, minimal API architecture — without one displacing the other.
Problem being explored
Most search-in-an-app implementations pick one approach: either keyword/SQL search, or full-blown AI semantic search. This project deliberately keeps both paths live side by side (/projects/search/{query} for DB search, /projects/aisearch/{query} for embedding-based semantic search) so the trade-off is visible and testable rather than assumed. It's a way of asking: when does semantic search actually add value over structured search, and when is it unnecessary overhead?
Design decisions
Minimal APIs over controller-based APIs — keeps the endpoint surface explicit and small, which matters when the API is doing double duty (data + AI orchestration) and readability of intent is a priority. Dapper + stored procedures over an ORM — favors explicit, predictable SQL for the data-backed paths, keeping query performance and behavior transparent rather than abstracted behind change-tracking or lazy loading. Separation of chat vs. semantic search into distinct endpoints rather than one combined "AI" endpoint — chat support and semantic search solve different problems (conversational Q&A vs. retrieval), and conflating them into a single endpoint would blur both the API contract and the reasoning inside ProjectAIService. Qdrant as the vector store, integrated via Microsoft.Extensions.VectorData rather than a hand-rolled vector client — keeps the vector-store abstraction swappable if the underlying store changes later, rather than coupling the app directly to Qdrant's client API throughout the codebase. Embeddings generated and upserted lazily (InitEmbeddingsAsync, only when the collection is missing) — avoids re-embedding on every startup, treating embeddings as a derived, cacheable artifact of the source data rather than something recomputed per request. System prompt constrained to the known project catalog — the chat assistant is explicitly restricted to answering from the available knowledge base rather than free-generating, which was a deliberate choice to keep AI output grounded and avoid fabricated recommendations.
What this demonstrates
Comfort integrating Microsoft.Extensions.AI abstractions (IChatClient, IEmbeddingGenerator) rather than hand-wiring provider SDKs directly, keeping the door open to swap the underlying model provider. Practical use of vector search alongside — not instead of — conventional relational search, reflecting a "right tool for the retrieval problem" mindset rather than defaulting to AI for everything. Applying the same architectural discipline (clear boundaries, swappable infrastructure, explicit contracts) from enterprise API work to a smaller, exploratory GenAI project.
- .NET 10 SDK
- SQL Server (or compatible) with the expected stored procedures (see Database section)
- Configuration values (API keys, connection string) configured as environment variables or in
appsettings.*
The API expects a SQL connection string named DefaultConnection and the following stored procedures to exist:
GetProjectsById- Returns project rows (used for listing and GetById)GetProjectFundingById- Returns funding allocations for a specific projectGetAllInvestors- (used by the service)GetProjectsSearchAllColumns- Free-text search across project columns
Populate the database with sample projects so the API and semantic search can return meaningful results.
Set the following configuration keys (example options):
ConnectionStrings:DefaultConnection- SQL connection stringGitHubModels:Token- API key for OpenAI-compatible models (the code usesmodels.github.aiendpoint)- Vector DB configuration (Qdrant) - the project calls
builder.AddQdrantClient("vectordb")andAddQdrantCollection("project-vectors"); configure the host/credentials according to your environment. These values can be set via the appsettings used by the shared defaults.
- Open the solution in Visual Studio 2026.
- Ensure
DefaultConnectionandGitHubModels:Tokenare set in user secrets or environment variables. - Start the
AspireIfus_ApiServiceproject first (it hosts the API and AI endpoints). - Start
AspireIfus.WebApp(Blazor) and navigate to/projects.
Recommended: Run both projects concurrently (set multiple startup projects) so the Blazor app can call the API.
The API exposes project related endpoints under /projects:
GET /projects- Get all projectsGET /projects/{id}- Get project by idGET /projects/search/{query}- Database-backed search across projectsGET /projects/support/{query}- AI chat support (returns a short chat response driven by models)GET /projects/aisearch/{query}- Semantic search using embeddings and vector store (Qdrant)
- The AI functionality uses an OpenAI-compatible client configured in
AspireIfus_ApiService/Program.cs. The application expects a token configured atGitHubModels:Tokenand communicates withhttps://models.github.ai/inferenceby default. - The semantic search uses an embedding generator and a Qdrant collection named
project-vectors. Embeddings are generated from project metadata and upserted into the collection automatically inProjectAIService.InitEmbeddingsAsync()when the collection is missing. - The system prompt used for the chat assistant is crafted for green energy analysis and restricts responses to project knowledge base facts. See
ProjectAIServicefor the exact rules.
This repository uses (and references in code) the following libraries, frameworks and concepts:
.NET 10(target framework)Blazor(Interactive Server components)Minimal APIs(MapGroup, IEndpointRouteBuilder, Results)Microsoft.Extensions.AI(chat + embedding abstractions:IChatClient,IEmbeddingGenerator,ChatMessage,ChatRole)OpenAIClient/ OpenAI-compatible client usage (model clients configured inProgram.cs)Microsoft.Extensions.VectorData(vector store types and attributes:VectorStoreCollection,VectorStoreKey,VectorStoreData,VectorStoreVector)Qdrant(vector DB client configured viaAddQdrantClient/AddQdrantCollection)Dapper(data access via stored procedures)Microsoft.Data.SqlClient(SQL Server connections)System.Text.Json(JSON serialization /GetFromJsonAsyncusage)HttpClient(typed clientProjectApiClient)OpenAPI/ Swagger helpers (AddOpenApi,MapOpenApi)Bootstrap(UI script referenced in Blazor page for modal dialogs)Stored Procedures(database access pattern used byDapperContext)
- The Blazor page
Components/Pages/Projects.razorlists projects and supports searching. It can toggle between database search and AI semantic search. - The client code is in
AspireIfus.WebApp/ApiClients/ProjectApiClient.csand calls the API endpoints described above.
- "Missing configuration: GitHubModels:Token." — set
GitHubModels:Tokenin user secrets or environment variables. - Connection errors — verify
DefaultConnectionand that the database is reachable. Confirm the required stored procedures exist. - Qdrant / vector store issues — verify your vector DB is running and the host/credentials are configured in the same configuration used by
AddQdrantClient.
- Add or adjust stored procedures to match your data model.
- To change the model or embedding engine, update
Program.cswhereOpenAIClientis configured and whereGetChatClient/GetEmbeddingClientare selected. ProjectAIServicewill only recommend projects that match the prompt rules and the available project catalog — it will not invent data.
This repository is provided as sample code. No license file is included — add one if you intend to publish or share the project.