Packages
Every published package. All of them are on nuget.org, with no private feed and no token, and all of them ship together on one version. Project templates reference the right ones for you; this page is for assembling a project by hand.
Source generator packages are referenced as analysers:
<PackageReference Include="Hardened.Web.SourceGenerator" Version="..."
OutputItemType="Analyzer" ReferenceOutputAssembly="false" />Framework
Core
| Package | Contents |
|---|---|
Hardened.Shared.Runtime | Module entry points, configuration binding, environment, application lifecycle, metrics |
Hardened.Shared.Testing | [HardenedTestEntryPoint], [Mock], ITestContext, the retry engine and the test attribute interfaces. Needs a runner package beside it |
Hardened.Shared.Testing.xUnit | [HardenedTest] for xUnit v3 |
Hardened.Shared.Testing.NUnit | [HardenedTest] for NUnit |
Hardened.SourceGeneration.Testing | Harness for testing source generators against a real compilation |
Requests
| Package | Contents |
|---|---|
Hardened.Requests.Abstract | IExecutionContext, IExecutionRequest, IExecutionResponse, IExecutionFilter |
Hardened.Requests.Runtime | The pipeline: filters, serialisation, validation, error handling |
Hardened.Requests.Testing | Test doubles, and the transport conformance suite every IExecutionRequest is held to |
Hardened.Requests.Serializers.Newtonsoft | A Newtonsoft.Json serialiser, for payloads System.Text.Json cannot round-trip |
Hardened.Requests.Caching.Memory | [HardenedMemoryResponseCache], an in-process IResponseCacheStore. Nothing registers a store by default; see Response caching |
Web
| Package | Contents |
|---|---|
Hardened.Web.Runtime | Routing, CORS, the OpenAPI document and reference page |
Hardened.Web.Kestrel.Runtime | [KestrelRuntime] and HardenedKestrelApplication. Kestrel without the ASP.NET Core request pipeline, and the host to reach for first |
Hardened.Web.AspNetCore.Runtime | [AspNetCoreRuntime] and app.UseHardened(), when you need ASP.NET Core's middleware, authentication or hosting diagnostics |
Hardened.Web.StaticContent | Static file serving, manifests and content compression |
Hardened.Web.Testing | ITestWebApp, TestWebRequest, TestWebResponse, PipelineHttpMessageHandler, the credential attributes, ITestClientFactory<T>, ITestClientRoute, Returns<T>(), LastResponse. Names no client generator |
Hardened.Web.Kestrel.Testing | [KestrelTesting]: runs a test carrying [KestrelRuntime] on Kestrel, on a loopback port |
Hardened.Web.AspNetCore.Testing | [AspNetCoreTesting]: the same for [AspNetCoreRuntime], inside a real WebApplication |
No package ships a client. The src/Todos.Client project the hardened-web template scaffolds depends on Microsoft.Kiota.Bundle alone; see Clients.
Client testing
One package per generator, because a Kiota method and a Refit method hand an answer back in different shapes. Each names its generator's runtime and nothing else of it.
| Package | Contents |
|---|---|
Hardened.Kiota.Testing | [assembly: KiotaTesting]: the route that makes every Kiota client a test parameter built over the pipeline, and reads what a call through one answered for Returns<T>() |
Hardened.Refit.Testing | [assembly: RefitTesting]: the same for a Refit interface, generated by Refitter with --use-api-response or written by hand |
The vocabulary both assert in, Created<T>, NotFound<T>, NoContent and the rest, is Hardened.Requests.Abstract.Responses; see Clients.
Templates
Two unrelated senses of the word, in two packages.
| Package | Contents |
|---|---|
Hardened.Templates | The dotnet new project templates: hardened-web, hardened-function, hardened-library. See Project templates |
Hardened.Templates.RazorBlade | View rendering: RazorTemplates, HardenedHtmlTemplate<T>. Renders .cshtml with no ASP.NET Core dependency. See Views |
IHardenedResponseOutput<T>, what a view implements, and the [TemplateBase] / [TemplateContentType] vocabulary a rendering engine's marker declares both live in Hardened.Requests.Abstract, so naming a view or shipping another engine does not depend on RazorBlade.
Console
| Package | Contents |
|---|---|
Hardened.Commands | [Command], [Option], ICommandHandler<T>, the parser and help printer |
Hardened.Console.SourceGenerator | Console entry points and command definitions |
Retired
Both are last published at 0.4.0-rc1000, their source is no longer in the repository, and nothing will be released on that line again. They will not have the fixes the packages above carry, and mixing release lines within one application is not a supported combination.
Source generators
Analyzers do not flow through a package reference, so a generator has to be referenced by the project that needs it. Referencing only the runtime packages produces an application that compiles and answers 404 to everything.
| Package | Emits |
|---|---|
Hardened.Library.SourceGenerator | Module wiring for [HardenedModule]: PopulateServiceCollection, CreateServiceProvider and the configuration implementations. Carries Hardened.DependencyModules.SourceGenerator inside it, so that one is not referenced separately |
Hardened.Web.SourceGenerator | Route tables and request handlers for [Get], [Post], [Put], [Delete], [Patch] |
Hardened.Function.SourceGenerator | Function handlers for [HardenedFunction] |
Hardened.Validation.SourceGenerator | Validators from constraint attributes, and their registration |
Hardened.OpenApi.SourceGenerator | Front end: an OpenAPI document into the normalised model |
Hardened.Smithy.SourceGenerator | Front end: a Smithy model into the normalised model. Needs the Smithy CLI on PATH |
Hardened.Idl.SourceGenerator | Back end for both front ends: models, service interfaces, handlers, routes and validation |
Hardened.SourceGenerator | The shared generator library the others build on. Not referenced directly |
Functions
Provider-neutral. The trigger attributes name a source and no cloud, so these packages are the same whichever runtime serves them; see Triggers.
| Package | Contents |
|---|---|
Hardened.Functions.Runtime | [Queue], [Topic], [Timer], [Event], [Change], [Stream], [Blob], and BatchFailureMode |
Hardened.Functions.Testing | [assembly: FunctionTesting]: the generated trigger façades a test sends through |
AWS
On the framework's version line, and released with it. One host package, and one adapter per source — an adapter is a package rather than a flag so a function carries only the event models it can reach.
The host
| Package | Contents |
|---|---|
Hardened.Aws.Lambda.Runtime | HardenedLambdaBootstrap, the invocation loop, the deadline, structured CloudWatch logging and embedded metrics, and LambdaEmulator for running locally |
Hardened.Aws.Lambda | The host and every adapter in one reference. Convenience rather than the recommended reference: it puts every Amazon.Lambda event assembly in the bundle whatever the function is triggered by, which is the state the package split exists to end. HRDF003 reports each adapter the project does not use |
Adapters
| Package | Serves | Module |
|---|---|---|
Hardened.Aws.Lambda.ApiGateway | [Get], [Post], [Put], [Patch], [Delete] | [ApiGatewayModule] |
Hardened.Aws.Lambda.Invoke | [HardenedFunction] | [InvokeModule] |
Hardened.Aws.Lambda.Sqs | [Queue] | [SqsModule] |
Hardened.Aws.Lambda.Sns | [Topic] | [SnsModule] |
Hardened.Aws.Lambda.EventBridge | [Timer] and [Event] | [EventBridgeModule] |
Hardened.Aws.Lambda.DynamoDb | [Change], with [NewImage] and [OldImage] | [DynamoDbStreamsModule] |
Hardened.Aws.Lambda.Kinesis | [Stream] | [KinesisModule] |
Hardened.Aws.Lambda.S3 | [Blob] | [S3Module] |
An application does not normally write a module out. The trigger on a handler binds it, through a build property the adapter package declares. [ApiGatewayModule] is the exception, because a web host's routes are in a library the generator cannot see; and any adapter is written out to set ReportBatchItemFailures, which is a fact about the deployment rather than the code.
Clients
Not a host and not an adapter, so it stands apart from the Lambda packages: an application uses these on Lambda, on Kestrel or in a console the same way.
| Package | Contents |
|---|---|
Hardened.Aws.DynamoDbClient | IDynamoDbClientProvider, DynamoDbOptions, [DynamoDbClientModule]. See DynamoDB client |
Hardened.Aws.DynamoDbClient.Testing | [LocalDynamoDb] and LocalDynamoDb: DynamoDB Local in a Testcontainers container |
Note that Hardened.Aws.Lambda.DynamoDb is a different thing — the Streams adapter that serves [Change], not a client. The module names say which is which: [DynamoDbClientModule] here, [DynamoDbStreamsModule] there.
Testing
| Package | Contents |
|---|---|
Hardened.Aws.Lambda.Testing | [assembly: LambdaTesting], which delivers through the real AWS envelope rather than straight into the pipeline, and [LambdaWebTesting], API Gateway as a test host |
The Hardened.Amz line
The AWS packages were Hardened.Amz.* until 0.22.0-rc1000, in a repository of their own. That line has stopped, is not moving, and is not being renamed — the packages above replace it, with different module attributes and a different test harness. They stay on nuget.org, restorable, and mixing the two lines within one application is not a supported combination.
The DynamoDB client and its test container are the exception: they were the only part of that line that was not a host, so they came across as Hardened.Aws.DynamoDbClient and Hardened.Aws.DynamoDbClient.Testing rather than being rebuilt.
Versioning
Everything releases on one version line, from a v* tag:
| Released | Continuous feed | |
|---|---|---|
| Every package on this page | {line}-rc1000 | {line}-preview{build} on every push to main |
Hardened.Amz.*, retired | 0.22.0-rc1000, its last | none |
The current line is 0.30.0-rc1000. Releases go to nuget.org; the continuous feed is GitHub Packages. Under one line, preview sorts below rc, so a preview never shadows the release it precedes.
Pin exact versions across a solution. The generated code and the runtime it targets ship together, so mixing framework builds within one application is not a supported combination.
Avoid a floating pin. A float that stops matching anything new does not fail. It keeps resolving whatever it last found, with a green build throughout.
The Lambda templates used to float their Hardened.Amz pin, because two repositories released in sequence and for a window an exact pin named a version that did not exist yet. There is one repository and one line now, so every template pins $(HardenedVersion) like everything else.