Skip to main content

Overview

NuGet.Services.Validation is a shared library that sits at the center of NuGet Gallery’s asynchronous validation pipeline. It provides:
  • Entity Framework entities and DbContext (ValidationEntitiesContext) — the canonical data model for all validation state stored in the dedicated Validation SQL database.
  • Service Bus messaging contracts — serialization/deserialization of the four message types that drive the validation workflow (StartValidation, ProcessValidationSet, CheckValidationSet, CheckValidator).
  • EF6 code-first migrations — 20+ incremental migrations that have evolved the schema from 2017 through 2024, covering signing, scanning, revalidation, symbols, and content-scan features.
  • Cross-cutting enums and data objects shared between the Gallery front-end (NuGetGallery) and the back-end Orchestrator / validator workers.
The library targets both net472 (for legacy IIS-hosted services) and netstandard2.1 (for newer worker roles).
The ValidationEntitiesContext static constructor explicitly calls Database.SetInitializer<ValidationEntitiesContext>(null), disabling automatic EF migrations at runtime. All schema changes must be applied deliberately via the Migrations classes or a dedicated migration tool.

This project is not an executable — it is a shared assembly consumed by:
  • NuGetGallery — to enqueue validation requests and read signing state.
  • NuGet.Services.Validation.Orchestrator — to orchestrate individual validators and persist their results.
  • Individual validator workers — which write back ValidatorStatus rows to communicate progress.

Key Files and Classes


Dependencies

NuGet Package References

Internal Project References


Notable Patterns and Implementation Details

Versioned Service Bus Schemas

Each message type is serialized using a private inner class annotated with [Schema(Name=..., Version=1)]. The deserializer switches on the schema name string read from the brokered message header, making it straightforward to add Version=2 classes later without breaking existing consumers.

Discriminated-Union Message Envelope

PackageValidationMessageData enforces exactly one non-null payload out of four possible data slots at construction time. Passing more than one non-null payload throws ArgumentException, preventing message type mismatches silently.

Multi-Schema SQL Layout

Signing entities live in the signature schema; scan entities in the scan schema; everything else in dbo. This makes permission scoping and backup partitioning cleaner at the SQL Server level.

Dual-Target Library

The project targets both net472 and netstandard2.1. EF6 is Windows/full-framework-only for actual DB access, but the entity POCOs and message contracts compile cleanly under netstandard2.1 for use in lightweight cross-platform services.
The BatchId column on ValidatorStatus is intentionally ignored in the base ValidationEntitiesContext. Derived contexts (used in other internal services that have the column) override ConfigureBatchIdProperty() to enable it. Forgetting to override in a derived context will silently drop the column from EF’s model.
Certificate thumbprints are stored as varchar (not nvarchar) and sized at 256 characters — large enough to accommodate future hash algorithms beyond SHA-256 without requiring a schema migration.
ValidationDbContextFactory supports three construction modes: a static delegate (ValidationEntitiesContextFactory), a direct connection string, or the default "Validation.SqlServer" named connection. The static delegate is useful for injecting AAD token-based DbConnection objects in Azure-hosted migration tools.

Message Flow Summary