Before making ANY changes, verify you're in the correct repository:
git remote -v- ✅ CORRECT:
origin .../algolia/api-clients-automation.git→ You may proceed - ❌ WRONG:
origin .../algolia/algoliasearch-client-csharp.git→ STOP! This is the PUBLIC repository
If you're in algoliasearch-client-csharp: Do NOT make changes here. All changes must go through api-clients-automation. PRs and commits made directly to the public repo will be discarded on next release.
Before editing ANY file, verify it's hand-written by checking config/generation.config.mjs:
// In generation.config.mjs - patterns WITHOUT '!' are GENERATED (do not edit)
'clients/algoliasearch-client-csharp/**', // Generated by default
'!clients/algoliasearch-client-csharp/algoliasearch/Clients/AlgoliaConfig.cs', // Hand-written ✓
'!clients/algoliasearch-client-csharp/algoliasearch/Exceptions/**', // Hand-written ✓
'!clients/algoliasearch-client-csharp/algoliasearch/Serializer/**', // Hand-written ✓
'!clients/algoliasearch-client-csharp/algoliasearch/Utils/**', // Hand-written ✓
'!clients/algoliasearch-client-csharp/algoliasearch/Http/**', // Hand-written ✓
'!clients/algoliasearch-client-csharp/algoliasearch/Transport/**', // Hand-written ✓
'!clients/algoliasearch-client-csharp/algoliasearch/Models/Common/**', // Hand-written ✓Hand-written (safe to edit):
algoliasearch/Clients/AlgoliaConfig.cs- Configuration basealgoliasearch/Exceptions/**- Exception typesalgoliasearch/Serializer/**- JSON serializationalgoliasearch/Utils/**- Utility classesalgoliasearch/Http/**- HTTP client wrapperalgoliasearch/Transport/**- Transport layer, retry logicalgoliasearch/Models/Common/**- Common model types
Generated (DO NOT EDIT):
algoliasearch/Clients/*Client.cs(except AlgoliaConfig.cs)algoliasearch/Models/**(except Models/Common/**)- Root project files
- Files:
PascalCase.csmatching class name - Classes/Interfaces/Enums:
PascalCase - Methods/Properties:
PascalCase - Private fields:
_camelCase - Parameters/Local variables:
camelCase - Constants:
PascalCase
- .NET default formatting
- Run:
yarn cli format csharp clients/algoliasearch-client-csharp
- Use
async/awaitfor asynchronous operations - Nullable reference types enabled (C# 8+)
- Use
varfor local variables when type is obvious - LINQ for collections
- Pattern matching in switch expressions
- HTTP: HttpClient (System.Net.Http)
- JSON: System.Text.Json
- Build: .NET SDK / MSBuild
- Target: .NET 8.0+
// Transport/ - HTTP layer with retry
public class HttpTransport : ITransport
{
private readonly HttpClient _httpClient;
private readonly RetryStrategy _retryStrategy;
public async Task<T> ExecuteAsync<T>(HttpRequest request)
{
// Retry logic with host failover
}
}// All API methods have async versions
public async Task<SearchResponse> SearchAsync(SearchParams searchParams)
// Usage
var response = await client.SearchAsync(searchParams);
// With cancellation
var response = await client.SearchAsync(searchParams, cancellationToken);// Exceptions/
public class AlgoliaException : Exception { }
public class AlgoliaApiException : AlgoliaException
{
public int HttpStatusCode { get; }
public string HttpBody { get; }
}
public class AlgoliaUnreachableHostsException : AlgoliaException { }// WRONG - blocking on async
var response = client.SearchAsync(params).Result; // Deadlock risk!
// CORRECT - await properly
var response = await client.SearchAsync(params);
// If you must block (avoid), use
var response = client.SearchAsync(params).GetAwaiter().GetResult();// C# 8+ nullable annotations
string? nullable = null; // Can be null
string nonNull = ""; // Cannot be null
// Null-conditional
var length = nullable?.Length;
// Null-coalescing
var value = nullable ?? "default";
// Null-forgiving (use sparingly)
var sure = nullable!;// Clients are disposable - use using statement
using var client = new SearchClient("APP_ID", "API_KEY");
await client.SearchAsync(params);
// Or explicit disposal
var client = new SearchClient("APP_ID", "API_KEY");
try
{
await client.SearchAsync(params);
}
finally
{
client.Dispose();
}// Use LINQ for collections
var filtered = response.Hits
.Where(h => h.Score > 0.5)
.Select(h => h.ObjectID)
.ToList();// Models use System.Text.Json
[JsonPropertyName("objectID")]
public string ObjectId { get; set; }
// Custom converters in Serializer/# From repo root (api-clients-automation)
yarn cli build clients csharp # Build C# client
yarn cli cts generate csharp # Generate CTS tests
yarn cli cts run csharp # Run CTS tests
yarn cli format csharp clients/algoliasearch-client-csharp
# From client directory
cd clients/algoliasearch-client-csharp
dotnet build # Build solution
dotnet test # Run tests
dotnet format # Format code