This project contains multiple examples demonstrating different ways to use the Weaviate C# client.
Run without arguments to see an interactive menu:
dotnet run --project src/ExampleYou'll see:
=== Weaviate C# Client Examples ===
Choose an example to run:
1. Traditional Example (cats.json batch insert)
2. Dependency Injection Example
3. Multiple Clients Example
4. Different Configs Example
5. Configuration Example (from appsettings.json)
6. Lazy Initialization Example
7. Connect Helper Example
Enter your choice (1-7):
Run a specific example by name:
dotnet run --project src/Example -- traditional
dotnet run --project src/Example -- di
dotnet run --project src/Example -- multiple
dotnet run --project src/Example -- configs
dotnet run --project src/Example -- configuration
dotnet run --project src/Example -- lazy
dotnet run --project src/Example -- connectFile: TraditionalExample.cs
Classic usage without dependency injection. Demonstrates:
- Using
Connect.Local()to create a client - Batch insertion of data
- Basic queries (FetchObjects, FetchObjectByID, FetchObjectsByIDs)
- Vector similarity search with NearVector
- BM25 full-text search
- Iterator pattern for large result sets
When to use: Simple scripts, console applications, quick prototypes.
var client = await Connect.Local();
var collection = client.Collections.Use<Cat>("Cat");
var results = await collection.Query().Limit(10).Execute();File: DependencyInjectionExample.cs
Modern ASP.NET Core-style dependency injection with eager initialization.
What it shows:
- Registering Weaviate with
AddWeaviateLocal() - Eager initialization via
IHostedService(client initializes on app startup) - Injecting
WeaviateClientinto services - Using ILogger for structured logging
When to use: ASP.NET Core applications, web APIs, long-running services.
// Startup
services.AddWeaviateLocal(
hostname: "localhost",
restPort: 8080,
grpcPort: 50051,
eagerInitialization: true
);
// In your service
public class CatService
{
private readonly WeaviateClient _weaviate;
public CatService(WeaviateClient weaviate)
{
_weaviate = weaviate; // Already initialized!
}
}File: MultipleClientsExample.cs
Using multiple named Weaviate clients simultaneously.
What it shows:
- Registering multiple clients with different configurations
- Using
IWeaviateClientFactoryto get clients by name - Multi-environment scenarios (prod, staging, local)
- Syncing data between environments
When to use:
- Multi-region deployments
- Multi-tenant architectures
- Different databases for analytics vs operations
- Working with multiple Weaviate clusters
// Register multiple clients
services.AddWeaviateClient("production", options => { ... });
services.AddWeaviateClient("staging", options => { ... });
services.AddWeaviateClient("local", "localhost", 8080, 50051);
// Use in service
public class MyService
{
private readonly IWeaviateClientFactory _factory;
public async Task ProcessAsync()
{
var prodClient = await _factory.GetClientAsync("production");
var stagingClient = await _factory.GetClientAsync("staging");
// Each has independent configuration
}
}File: DifferentConfigsExample.cs
Demonstrates how each named client can have completely different settings.
What it shows:
- Different hosts and ports per client
- Different SSL settings
- Different authentication (API key, OAuth, OIDC, none)
- Different timeouts per client
- Custom headers per client
- Different retry policies
When to use: When you need fine-grained control over each client's behavior.
// Production: SSL + API key + short timeouts
services.AddWeaviateClient("production", options =>
{
options.RestEndpoint = "prod.weaviate.cloud";
options.UseSsl = true;
options.Credentials = Auth.ApiKey("key");
options.QueryTimeout = TimeSpan.FromSeconds(30);
});
// Local: No SSL, no auth, long timeouts for debugging
services.AddWeaviateClient("local", options =>
{
options.RestEndpoint = "localhost";
options.UseSsl = false;
options.Credentials = null;
options.QueryTimeout = TimeSpan.FromMinutes(5);
});File: DependencyInjectionExample.cs → ConfigurationExample class
Reading Weaviate settings from appsettings.json.
What it shows:
- Using
IConfigurationwithAddWeaviate() - Externalizing connection settings
- Environment-specific configuration
When to use: Production applications where settings should be configurable without code changes.
appsettings.json:
{
"Weaviate": {
"RestEndpoint": "localhost",
"RestPort": 8080,
"GrpcPort": 50051,
"UseSsl": false
}
}Code:
services.AddWeaviate(
context.Configuration.GetSection("Weaviate"),
eagerInitialization: true
);File: DependencyInjectionExample.cs → LazyInitializationExample class
Client initializes on first use instead of startup.
What it shows:
- Setting
eagerInitialization: false - Manually triggering initialization with
InitializeAsync() - Checking initialization status with
IsInitialized
When to use:
- Applications where Weaviate might not always be needed
- Faster startup times
- On-demand client creation
services.AddWeaviateLocal(eagerInitialization: false);
// Later...
var client = serviceProvider.GetRequiredService<WeaviateClient>();
Console.WriteLine(client.IsInitialized); // False
await client.InitializeAsync(); // Initialize now
Console.WriteLine(client.IsInitialized); // TrueFile: DependencyInjectionExample.cs → ConnectHelperExample class
Shows that traditional Connect.Local() and Connect.Cloud() still work.
What it shows:
- Backward compatibility
- Fully async, no blocking calls
- Simple one-liner client creation
When to use: Quick scripts, simple applications, backward compatibility.
// Local
var client = await Connect.Local();
// Cloud
var client = await Connect.Cloud(
clusterEndpoint: "my-cluster.weaviate.cloud",
apiKey: "my-api-key"
);All examples require:
- A running Weaviate instance (default:
localhost:8080) - .NET 8.0 or later
docker run -d \
-p 8080:8080 \
-p 50051:50051 \
-e ENABLE_MODULES=text2vec-weaviate \
-e DEFAULT_VECTORIZER_MODULE=text2vec-weaviate \
cr.weaviate.io/semitechnologies/weaviate:latest| Scenario | Recommended Example |
|---|---|
| Quick script or console app | Traditional (#1) or Connect Helper (#7) |
| ASP.NET Core web API | Dependency Injection (#2) |
| Multiple Weaviate clusters | Multiple Clients (#3) |
| Per-client custom settings | Different Configs (#4) |
| Configuration-driven setup | Configuration (#5) |
| Faster startup, on-demand init | Lazy Initialization (#6) |
| Learning the basics | Traditional (#1) |
| Production applications | Dependency Injection (#2) + Configuration (#5) |
// Program.cs or Startup.cs
builder.Services.AddWeaviateLocal(
hostname: builder.Configuration["Weaviate:Host"] ?? "localhost",
restPort: ushort.Parse(builder.Configuration["Weaviate:Port"] ?? "8080"),
eagerInitialization: true
);
// Controller
[ApiController]
[Route("[controller]")]
public class SearchController : ControllerBase
{
private readonly WeaviateClient _weaviate;
public SearchController(WeaviateClient weaviate)
{
_weaviate = weaviate;
}
[HttpGet]
public async Task<IActionResult> Search([FromQuery] string query)
{
var collection = _weaviate.Collections.Use<Product>("Product");
var results = await collection.Query().BM25(query).Limit(10).Execute();
return Ok(results.Objects());
}
}public class WeaviateBackgroundService : BackgroundService
{
private readonly WeaviateClient _weaviate;
private readonly ILogger<WeaviateBackgroundService> _logger;
public WeaviateBackgroundService(
WeaviateClient weaviate,
ILogger<WeaviateBackgroundService> logger)
{
_weaviate = weaviate;
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
// Process data periodically
await ProcessDataAsync();
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
}
}
}For more information:
- Documentation Index - All Managed client documentation
- Getting Started - 5-minute quickstart with attributes
- Dependency Injection - DI patterns for Managed collections
- API Reference - Complete ManagedCollection API
Can't connect to Weaviate:
- Ensure Weaviate is running:
docker ps - Check ports are correct: 8080 (REST), 50051 (gRPC)
- Verify endpoint:
curl http://localhost:8080/v1/.well-known/ready
Build errors about Host:
- Ensure
Microsoft.Extensions.Hostingpackage is referenced inExample.csproj
Initialization timeout:
- Increase
initTimeoutin options - Check network connectivity to Weaviate
- Verify Weaviate is fully started and healthy
The WebApi and WebApp projects demonstrate a complete full-stack AI product search application:
- WebApi: ASP.NET Core Minimal API backend with vector search endpoints
- WebApp: SvelteKit frontend with modern UI and type-safe API client
┌─────────────────┐
│ SvelteKit UI │ ← TypeScript, SSR, reactive components
│ (Port 5173) │
└────────┬────────┘
│ HTTP/REST
▼
┌─────────────────┐
│ ASP.NET Core │ ← Minimal API, DI, migrations
│ WebApi (5000) │
└────────┬────────┘
│ C# Client
▼
┌─────────────────┐
│ Weaviate C# │ ← Managed Client (ORM layer)
│ Managed Client │
└────────┬────────┘
│ REST/gRPC
▼
┌─────────────────┐
│ Weaviate DB │ ← Vector database (1.34.0)
│ (Port 8080) │ with text2vec-transformers
└─────────────────┘
- Semantic Search: Find products by meaning using vector embeddings
- Hybrid Search: Combine vector and keyword search for optimal results
- BM25 Keyword Search: Traditional full-text search
- Smart Recommendations: Vector similarity-based product suggestions
- Faceted Filtering: Filter by category, price, rating, and brand
- Type-Safe Architecture: End-to-end TypeScript and C# type safety
cd src/Example
docker compose up -dThis starts:
- Weaviate vector database (port 8080)
- text2vec-transformers vectorizer
Wait ~10 seconds for Weaviate to be ready:
curl http://localhost:8080/v1/.well-known/ready # Should return "true"cd src/Example/WebApi
dotnet runThe API will be available at http://localhost:5000
On first run, the backend will:
- Create the
Productcollection in Weaviate - Generate and insert 50 sample products
- Vectorize all products using text2vec-transformers
cd src/Example/WebApp
npm install
npm run devThe UI will be available at http://localhost:5174
The 3-step approach above is recommended for development and works reliably. Here are alternatives with their trade-offs:
Build locally, run in Docker - avoids ARM/x86 build issues:
# 1. Build everything locally
./build-for-docker.sh
# 2. Start all services (including backend/frontend in containers)
docker compose -f docker-compose.dev.yml upKnown Limitations:
⚠️ Server-side rendering (SSR) data fetching has issues in containerized SvelteKit⚠️ Homepage won't show products until you interact with the page (client-side hydration works)⚠️ Requires local .NET SDK and Node.js for build step
This approach works for:
- ✅ Client-side rendered pages
- ✅ Search functionality
- ✅ Interactive features after page load
- ✅ Production builds without SSR
When to use: You need everything containerized and can accept SSR limitations, or disable SSR entirely.
If you prefer docker run over docker-compose:
# Start Weaviate services
./start-weaviate-docker.sh
# Then run backend/frontend manually (same as Quick Start steps 2-3)
cd WebApi && dotnet run
cd WebApp && npm run dev
# Stop when done
./stop-weaviate-docker.shThis approach:
- ✅ No docker-compose dependency
- ✅ Direct control over containers
- ✅ Easy to customize individual containers
For automated deployments, use the included docker-compose.yml for Weaviate infrastructure, then deploy backend/frontend separately to your platform of choice (Azure, AWS, GCP, Kubernetes, etc.).
See ci/start_weaviate.sh in the root for integration with existing CI pipelines.
Open http://localhost:5174 in your browser and try:
- Semantic Search: Search for "device for taking photos" (finds cameras)
- Hybrid Search: Combine meaning with keywords
- Product Details: Click any product to see similar recommendations
- Filters: Use category, price, and rating filters
GET /health- Health checkGET /api/products- List products with filtersGET /api/products/{id}- Get single productGET /api/products/{id}/similar- Get similar products (NearObject)GET /api/products/facets- Get category and brand countsPOST /api/search- Main search endpoint (semantic/hybrid/keyword)GET /api/reviews?productId={id}- Get product reviewsPOST /api/reviews/search- Search reviews (BM25)
- WebApi README - Backend documentation
- WebApp README - Frontend documentation
- DEMO_SCRIPT.md - Step-by-step demo guide
# Health check
curl http://localhost:5000/health
# Get products
curl "http://localhost:5000/api/products?limit=5"
# Semantic search
curl -X POST http://localhost:5000/api/search \
-H "Content-Type: application/json" \
-d '{"query":"laptop for work","mode":"semantic","limit":5}'
# Similar products
curl "http://localhost:5000/api/products/{uuid}/similar?limit=4"This demo shows:
- ✅ How easy it is to add vector search to a C# application
- ✅ The power of attribute-driven schema definition
- ✅ Automatic migrations for safe schema evolution
- ✅ Multiple search modes for different use cases
- ✅ Type safety from database to UI
- ✅ Modern full-stack architecture patterns