{"id":51256442,"url":"https://github.com/ImmediatePlatform/Immediate.Validations","last_synced_at":"2026-07-17T22:00:46.428Z","repository":{"id":237055783,"uuid":"793714610","full_name":"ImmediatePlatform/Immediate.Validations","owner":"ImmediatePlatform","description":"Source generated validations for Immediate.Handlers parameters","archived":false,"fork":false,"pushed_at":"2026-07-14T00:02:12.000Z","size":434,"stargazers_count":17,"open_issues_count":4,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-07-14T02:06:14.078Z","etag":null,"topics":["csharp-sourcegenerator","mediator","mediator-pattern","validation"],"latest_commit_sha":null,"homepage":"https://immediateplatform.dev/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ImmediatePlatform.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["viceroypenguin"]}},"created_at":"2024-04-29T18:24:12.000Z","updated_at":"2026-07-14T00:02:14.000Z","dependencies_parsed_at":"2024-05-23T01:25:16.008Z","dependency_job_id":"3bd3c8da-b74e-4582-bb9c-e21c1a670d43","html_url":"https://github.com/ImmediatePlatform/Immediate.Validations","commit_stats":null,"previous_names":["immediateplatform/immediate.validations"],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/ImmediatePlatform/Immediate.Validations","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImmediatePlatform%2FImmediate.Validations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImmediatePlatform%2FImmediate.Validations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImmediatePlatform%2FImmediate.Validations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImmediatePlatform%2FImmediate.Validations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ImmediatePlatform","download_url":"https://codeload.github.com/ImmediatePlatform/Immediate.Validations/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ImmediatePlatform%2FImmediate.Validations/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35597010,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-17T02:00:06.162Z","response_time":116,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp-sourcegenerator","mediator","mediator-pattern","validation"],"created_at":"2026-06-29T11:00:26.608Z","updated_at":"2026-07-17T22:00:46.420Z","avatar_url":"https://github.com/ImmediatePlatform.png","language":"C#","funding_links":["https://github.com/sponsors/viceroypenguin"],"categories":["Source Generators"],"sub_categories":["Validation"],"readme":"# Immediate.Validations\n\n[![NuGet](https://img.shields.io/nuget/v/Immediate.Validations.svg?style=plastic)](https://www.nuget.org/packages/Immediate.Validations/)\n[![GitHub release](https://img.shields.io/github/release/ImmediatePlatform/Immediate.Validations.svg)](https://GitHub.com/ImmediatePlatform/Immediate.Validations/releases/)\n[![GitHub license](https://img.shields.io/github/license/ImmediatePlatform/Immediate.Validations.svg)](https://github.com/ImmediatePlatform/Immediate.Validations/blob/master/license.txt) \n[![GitHub issues](https://img.shields.io/github/issues/ImmediatePlatform/Immediate.Validations.svg)](https://GitHub.com/ImmediatePlatform/Immediate.Validations/issues/) \n[![GitHub issues-closed](https://img.shields.io/github/issues-closed/ImmediatePlatform/Immediate.Validations.svg)](https://GitHub.com/ImmediatePlatform/Immediate.Validations/issues?q=is%3Aissue+is%3Aclosed) \n[![GitHub Actions](https://github.com/ImmediatePlatform/Immediate.Validations/actions/workflows/build.yml/badge.svg)](https://github.com/ImmediatePlatform/Immediate.Validations/actions)\n---\n\nImmediate.Validations is a source generator validating\n[`Immediate.Handlers`](https://github.com/ImmediatePlatform/Immediate.Handlers) handler parameters.\n\n## Installing Immediate.Validations\n\nYou can install [Immediate.Validations with NuGet](https://www.nuget.org/packages/Immediate.Validations):\n\n    Install-Package Immediate.Validations\n    \nOr via the .NET Core command line interface:\n\n    dotnet add package Immediate.Validations\n\nEither command, from Package Manager Console or .NET Core CLI, will download and install Immediate.Validations.\n\n### Creating Validation Classes\n\nIndicate that a class should be validated by adding the `[Validate]` attribute and `IValidationTarget\u003c\u003e` interface:\n\n```cs\n[Validate]\npublic partial record Query : IValidationTarget\u003cQuery\u003e;\n```\n\nWhen Nullable Reference Types is enabled, any non-nullable reference types are automatically checked for `null`. Other\nvalidations are available like so:\n\n```cs\n[Validate]\npublic partial record Query : IValidationTarget\u003cQuery\u003e\n{\n\t[GreaterThan(0)]\n\tpublic required int Id { get; init; }\n}\n```\n\n### Referencing Other Properties\n\nSince attributes cannot reference anything other than constant strings, the way to reference static and instance\nproperties, fields, and methods is to use the `nameof()` to identify which property, field, or method should be used. Example:\n\n```cs\n[Validate]\npublic partial record Query : IValidationTarget\u003cQuery\u003e\n{\n\t[GeneratedRegex(@\"^\\d+$\")]\n\tprivate static partial Regex AllDigitsRegex();\n\n\t[Match(regex: nameof(AllDigitsRegex))]\n\tpublic required string Id { get; init; }\n}\n```\n\n### Custom Messages\n\nProvide a custom message to any validation using the `Message` property of the attribute. This message will be parsed\nfor template parameters, which will be applied to the message before rendering to the validation result. The target property\nname is available as `{PropertyName}`, and it's value via `{PropertyValue}`. \n\nOther parameter values will be added using their property name suffixed with `Value` (for example, the\n`GreaterThanAttribute` uses a `comparison` parameter, so the value is available via `ComparisonValue`). If another\nproperty on the target class is referenced via `nameof(Property)`, the name of that property will be available using the\n`Name` suffix (for example, `ComparisonName` for the `comparison` property).\n\n```cs\n[Validate]\npublic partial record Query : IValidationTarget\u003cQuery\u003e\n{\n\t[GreaterThan(0, Message = \"'{PropertyName}' must be greater than '{ComparisonValue}'\")]\n\tpublic required int Id { get; init; }\n}\n```\n\n### Extending Validation Classes\n\nIf attributes are not enough to specify how to validate a class, an `AdditionalValidations` method can be used to write\nadditional validations for the class.\n\n```cs\n[Validate]\npublic partial record Query : IValidationTarget\u003cQuery\u003e\n{\n\tpublic required bool Enabled { get; init; }\n\tpublic required int Id { get; init; }\n\n\tprivate static void AdditionalValidations(\n\t\tValidationResult errors,\n\t\tQuery target\n\t)\n\t{\n\t\tif (target.Enabled)\n\t\t{\n\t\t\t// Use a lambda to use the default message or override message;\n\t\t\t// the message will be templated in the same way as attribute validations.\n\t\t\terrors.Add(\n\t\t\t\t() =\u003e GreaterThanAttribute.ValidateProperty(\n\t\t\t\t\ttarget.Id,\n\t\t\t\t\t0\n\t\t\t\t)\n\t\t\t);\n\t\t}\n\n\t\tif (false)\n\t\t{\n\t\t\t// Manually create a `ValidationError` and add it to the `ValidationResult`.\n\t\t\terrors.Add(\n\t\t\t\tnew ValidationError()\n\t\t\t\t{\n\t\t\t\t\tPropertyName = \"ExampleProperty\",\n\t\t\t\t\tErrorMessage = \"Example Message\",\n\t\t\t\t}\n\t\t\t)\n\t\t}\n\t}\n}\n```\n\n## Using Immediate.Validations\n\n### Validating instances directly\n\nAn instance of an IV object can be validated directly by calling `ClassName.Validate(instance);`. In the example above,\nthis would look like:\n\n```cs\npublic void Method(Query query)\n{\n\tvar results = Query.Validate(query);\n}\n```\n\nThe `results` object will contain information on whether the instance is valid, and if not, the validation failures that\noccurred during validation.\n\nIf you would like to throw an exception if the validation fails, you can call `ValidationException.ThrowIfInvalid()`. This\nmethod can be called using the `ValidationResult` returned from validation if you have already validated it, or using an\ninstance of the object if you would like to validate and throw. Examples:\n\n```cs\npublic void Method(Query query)\n{\n\tvar results = Query.Validate(query);\n\tValidationException.ThrowIfInvalid(results);\n\n\t// or\n\n\tValidationException.ThrowIfInvalid(query);\n}\n```\n\n### Using Immediate.Validations with [Immediate.Handlers](https://github.com/ImmediatePlatform/Immediate.Handlers)\n\nAdding code to explicitly validate the object in every method that needs to do so can be annoying. Immediate.Validations\nis intended to integrate primarily with Immediate.Handlers, and so it provides an IH `Behavior\u003c,\u003e` which can be used to\nautomatically add validation to every IH handler which has a request which is an `IValidation\u003c\u003e` object. Add\nImmediate.Validations to the Immediate.Handlers behaviors pipeline by including it in the list of default Behaviors for\nthe assembly:\n\n```cs\nusing Immediate.Validations.Shared;\n\n[assembly: Behaviors(\n\ttypeof(ValidationBehavior\u003c,\u003e)\n)]\n```\n\n### Using Immediate.Validations in an ASP.NET Core application\n\nThe result of doing the above is that when a parameter fails one or more validations, a `ValidationException` is thrown,\nwhich can be handled via ProblemDetails or any other infrastructure mechanism.\n\nExample using ProblemDetails:\n```cs\nbuilder.Services.AddProblemDetails(ConfigureProblemDetails);\n\npublic static void ConfigureProblemDetails(ProblemDetailsOptions options) =\u003e\n\toptions.CustomizeProblemDetails = c =\u003e\n\t{\n\t\tif (c.Exception is null)\n\t\t\treturn;\n\n\t\tc.ProblemDetails = c.Exception switch\n\t\t{\n\t\t\tValidationException ex =\u003e new ValidationProblemDetails(\n\t\t\t\tex\n\t\t\t\t\t.Errors\n\t\t\t\t\t.GroupBy(x =\u003e x.PropertyName, StringComparer.OrdinalIgnoreCase)\n\t\t\t\t\t.ToDictionary(\n\t\t\t\t\t\tx =\u003e x.Key,\n\t\t\t\t\t\tx =\u003e x.Select(x =\u003e x.ErrorMessage).ToArray(),\n\t\t\t\t\t\tStringComparer.OrdinalIgnoreCase\n\t\t\t\t\t)\n\t\t\t)\n\t\t\t{\n\t\t\t\tStatus = StatusCodes.Status400BadRequest,\n\t\t\t},\n\n\t\t\t// other exception handling as desired\n\n\t\t\tvar ex =\u003e new ProblemDetails\n\t\t\t{\n\t\t\t\tDetail = \"An error has occurred.\",\n\t\t\t\tStatus = StatusCodes.Status500InternalServerError,\n\t\t\t},\n\t\t};\n\n\t\tc.HttpContext.Response.StatusCode =\n\t\t\tc.ProblemDetails.Status\n\t\t\t?? StatusCodes.Status500InternalServerError;\n\t};\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FImmediatePlatform%2FImmediate.Validations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FImmediatePlatform%2FImmediate.Validations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FImmediatePlatform%2FImmediate.Validations/lists"}