{"kind":"AgentDefinition","metadata":{"namespace":"community","name":"azure-functions-csharp","version":"0.1.0"},"spec":{"agents_md":"---\ndescription: 'Guidelines and best practices for building Azure Functions in C# using the isolated worker model'\napplyTo: '**/*.cs, **/host.json, **/local.settings.json, **/*.csproj'\n---\n\n# Azure Functions C# Development\n\n## General Instructions\n\n- Always use the **isolated worker model** (not the legacy in-process model) for all new Azure Functions projects targeting .NET 6 or later.\n- Use `FunctionsApplication.CreateBuilder(args)` or `HostBuilder` in `Program.cs` for host setup and dependency injection.\n- Decorate function methods with `[Function(\"FunctionName\")]` and use strongly typed trigger and binding attributes.\n- Keep function methods focused — each function should do one thing and delegate business logic to injected services.\n- Never put business logic directly inside the function method body; extract it into testable service classes registered via DI.\n- Use `ILogger\u003cT\u003e` injected through the constructor, not `ILogger` passed as a function parameter, for consistent structured logging.\n- Always use `async/await` for all I/O-bound operations; never block with `.Result` or `.Wait()`.\n- Prefer `CancellationToken` parameters where supported to enable graceful shutdown.\n\n## Project Structure and Setup\n\n- Use the `Microsoft.Azure.Functions.Worker` and `Microsoft.Azure.Functions.Worker.Extensions.*` NuGet packages.\n- Register services in `Program.cs` using `builder.Services.Add*` extension methods for clean dependency injection.\n- Group related functions into separate classes by domain concern, not by trigger type.\n- Store configuration in `local.settings.json` for local development; use Azure App Configuration or Application Settings for deployed environments.\n- Never hardcode connection strings or secrets in code; always read from `IConfiguration` or environment variables.\n- Use Key Vault references (`@Microsoft.KeyVault(SecretUri=...)`) in App Settings for secrets in deployed environments.\n- Use `Managed Identity` (`DefaultAzureCredential`) for authenticating to Azure services — avoid connection strings with keys wherever possible.\n- Keep `host.json` tuned per trigger type: configure `maxConcurrentCalls`, `batchSize`, and retry policies at the host level.\n\n## Triggers\n\n- **HttpTrigger**: Use `AuthorizationLevel.Function` or higher for production endpoints; reserve `AuthorizationLevel.Anonymous` only for public-facing APIs with explicit justification. Use ASP.NET Core integration (`UseMiddleware`, `IActionResult` returns) when using the ASP.NET Core integration model.\n- **TimerTrigger**: Use NCRONTAB expressions (`\"0 */5 * * * *\"`) for schedules; avoid `RunOnStartup = true` in production as it executes immediately on every cold start.\n- **QueueTrigger / ServiceBusTrigger**: Configure `MaxConcurrentCalls`, dead-letter policies, and `MaxDeliveryCount` in `host.json` and Azure portal; handle `ServiceBusReceivedMessage` directly for advanced message control (complete, abandon, dead-letter).\n- **BlobTrigger**: Prefer Event Grid-based blob triggers (`Microsoft.Azure.Functions.Worker.Extensions.EventGrid`) over polling-based blob triggers for lower latency and reduced storage transaction costs.\n- **EventHubTrigger**: Set `cardinality` to `many` for batch processing; use `EventData[]` or `string[]` parameter types for batch mode; always checkpoint using the `EventHubTriggerAttribute`'s built-in checkpointing.\n- **CosmosDBTrigger**: Use the change feed trigger for event-driven processing of Cosmos DB changes; set `LeaseContainerName` and manage lease containers separately from data containers.\n\n## Input and Output Bindings\n\n- Use input bindings to read data declaratively rather than using SDKs directly inside function bodies where the binding covers the use case.\n- For multiple output bindings, define a custom return type with properties annotated with the appropriate output binding attributes (e.g., `[QueueOutput]`, `[BlobOutput]`, `[HttpResult]`).\n- Use `[BlobInput]` and `[BlobOutput]` for blob read/write; prefer `Stream` over `byte[]` for large blobs to avoid memory pressure.\n- Use `[CosmosDBInput]` for point reads and simple queries; for complex queries, inject `CosmosClient` via DI with `Managed Identity`.\n- Use `[ServiceBusOutput]` for single-message sends; inject `ServiceBusSender` via DI for batching or advanced send scenarios.\n- Avoid mixing SDK clients obtained via DI with binding-based I/O for the same resource — choose one pattern per resource to maintain consistency.\n\n## Dependency Injection and Configuration\n\n- Register all external clients (e.g., `BlobServiceClient`, `ServiceBusClient`, `CosmosClient`) as singletons using `services.AddAzureClients()` from the `Azure.Extensions.AspNetCore.Configuration.Secrets` package with `DefaultAzureCredential`.\n- Use `IOptions\u003cT\u003e` or `IOptionsMonitor\u003cT\u003e` for strongly typed configuration sections.\n- Avoid using `static` state in functions; all shared state should flow through DI-registered services.\n- Register `HttpClient` instances via `IHttpClientFactory` to manage connection pooling and avoid socket exhaustion.\n\n## Error Handling and Retry\n\n- Configure built-in retry policies in `host.json` using `\"retry\"` with `fixedDelay` or `exponentialBackoff` strategy for trigger-level retries.\n- For transient fault handling at the code level, use `Microsoft.Extensions.Http.Resilience` or Polly v8 (`ResiliencePipeline`) with retry, circuit breaker, and timeout strategies.\n- Always catch specific exceptions and log them with structured context (e.g., correlation ID, input identifier) before re-throwing or dead-lettering.\n- Use dead-letter queues for messages that fail after all retries; never silently swallow exceptions in function handlers.\n- For HTTP triggers, return appropriate `IActionResult` types (`BadRequestObjectResult`, `NotFoundObjectResult`) rather than throwing exceptions for expected error conditions.\n\n## Observability and Logging\n\n- Use `ILogger\u003cT\u003e` with structured log properties: `_logger.LogInformation(\"Processing message {MessageId}\", messageId)`.\n- Configure Application Insights via `builder.Services.AddApplicationInsightsTelemetryWorkerService()` and `builder.Logging.AddApplicationInsights()` in `Program.cs`.\n- Use `TelemetryClient` for custom events, metrics, and dependency tracking beyond what is automatically collected.\n- Set appropriate log levels in `host.json` under `\"logging\"` to avoid excessive telemetry costs in production.\n- Use `Activity` and `ActivitySource` from `System.Diagnostics` for distributed tracing context propagation between functions and downstream services.\n- Avoid logging sensitive data (PII, secrets, connection strings) in any log statement.\n\n## Performance and Scalability\n\n- Keep function startup time minimal: defer expensive initialization to lazy-loaded singletons, not the function constructor.\n- Use the Consumption plan for event-driven, unpredictable workloads; use Premium or Dedicated plans for low-latency, high-throughput, or VNet-integrated scenarios.\n- For CPU-intensive work, offload to a background `Task` or use Durable Functions rather than blocking the function host thread.\n- Batch operations where possible: process `IEnumerable\u003cEventData\u003e` or `ServiceBusReceivedMessage[]` arrays in a single function invocation rather than one message at a time.\n- Set `FUNCTIONS_WORKER_PROCESS_COUNT` and `maxConcurrentCalls` appropriately for the hosting plan and expected throughput.\n- Enable `WEBSITE_RUN_FROM_PACKAGE=1` in App Settings for faster cold starts by running directly from a deployment package.\n\n## Security\n\n- Always validate and sanitize HTTP trigger inputs before processing; use FluentValidation or Data Annotations.\n- Use `AuthorizationLevel.Function` with function keys stored in Key Vault for internal API-to-API calls.\n- Integrate Azure API Management (APIM) in front of HTTP-triggered functions for public-facing APIs to handle auth, rate limiting, and routing.\n- Restrict inbound access using App Service networking features (IP restrictions, Private Endpoints) for sensitive functions.\n- Never log request bodies containing PII or secrets.\n\n## Testing\n\n- Unit-test service classes independently of the function host using standard xUnit/NUnit with mocked dependencies.\n- Integration-test functions using `Azurite` (local Azure Storage emulator) and `TestServer` or the Azure Functions Core Tools.\n- Use the `Microsoft.Azure.Functions.Worker.Testing` helpers where available to construct mock `FunctionContext` instances.\n- Avoid testing the trigger plumbing itself; focus tests on the business logic extracted into services.\n\n## Existing Code Review Guidance\n\n- If a project uses the legacy **in-process model** (`FunctionsStartup`, `IWebJobsStartup`), suggest migrating to the isolated worker model and provide the migration path via `dotnet-isolated-process-guide`.\n- If hardcoded connection strings or storage account keys are found in code or config files, flag them and suggest replacing with `DefaultAzureCredential` and Key Vault references.\n- If `RunOnStartup = true` is set on a `TimerTrigger` in a production app, flag it as a risk and suggest using deployment slots or feature flags instead.\n- If `async void` is used in any function, flag it immediately — use `async Task` instead.\n- If retry logic is implemented manually with `Thread.Sleep` or `Task.Delay` inside a function, suggest replacing with host-level retry policies or Polly resilience pipelines.\n\n","description":"Guidelines and best practices for building Azure Functions in C# using the isolated worker model","import":{"commit_sha":"541b7819d8c3545c6df122491af4fa1eae415779","imported_at":"2026-05-18T20:05:35Z","license_text":"MIT License\n\nCopyright GitHub, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","owner":"github","repo":"github/awesome-copilot","source_url":"https://github.com/github/awesome-copilot/blob/541b7819d8c3545c6df122491af4fa1eae415779/instructions/azure-functions-csharp.instructions.md"},"manifest":{}},"content_hash":[112,131,134,5,199,237,124,12,200,75,186,152,85,86,126,11,17,217,144,175,157,42,206,175,137,133,251,58,40,50,213,106],"trust_level":"unsigned","yanked":false}
