Nazh.Specifiable.Generator
1.0.0
dotnet add package Nazh.Specifiable.Generator --version 1.0.0
NuGet\Install-Package Nazh.Specifiable.Generator -Version 1.0.0
<PackageReference Include="Nazh.Specifiable.Generator" Version="1.0.0"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="Nazh.Specifiable.Generator" Version="1.0.0" />
<PackageReference Include="Nazh.Specifiable.Generator"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add Nazh.Specifiable.Generator --version 1.0.0
#r "nuget: Nazh.Specifiable.Generator, 1.0.0"
#:package Nazh.Specifiable.Generator@1.0.0
#addin nuget:?package=Nazh.Specifiable.Generator&version=1.0.0
#tool nuget:?package=Nazh.Specifiable.Generator&version=1.0.0
Nazh.Specifiable.Generator
Roslyn source generator + code fix provider for Nazh.Specifiable. Generates the combinator members (And, Or, Xor, Not, Materialize, implicit conversion operators) for structs marked with [ValueSpecification], so you don't have to hand-write boilerplate for every structural specification you create.
Why
structs can't inherit implementation from a shared base class the way Specification<T> does for reference types. Without a generator, every custom ISpecification<T> struct would need its own copy-pasted And/Or/Xor/Not/Materialize/implicit-operator boilerplate. This generator writes that code for you, at compile time, with zero runtime cost.
What it does
Given:
using Nazh.Specifiable.Attributes;
using Nazh.Specifiable.Specifications;
[ValueSpecification]
public readonly partial struct IsAdultValueSpecification : ISpecification<Person>
{
public bool IsSatisfiedBy(Person entity) => entity.Age >= 18;
public Expression<Func<Person, bool>> AsExpression() => p => p.Age >= 18;
}
the generator emits a second partial declaration adding And, Or, Xor, Not, Materialize, and implicit conversions to Expression<Func<Person, bool>> / Func<Person, bool> — so you can immediately write:
var validUser = new IsAdultValueSpecification().And(hasValidEmail);
without writing any of that yourself.
Requirements
The target type must be:
- a
structorrecord struct - declared
partial - an implementer of
ISpecification<T>for exactly oneT
Diagnostics & code fixes
The generator validates these requirements and reports a diagnostic for each violation. A matching code fix is offered for every one — apply it (Ctrl+. / Quick Actions) to fix the declaration automatically instead of editing it by hand.
| Id | Severity | Problem | Code fix |
|---|---|---|---|
NSS001 |
Error | [ValueSpecification] applied to a non-struct type |
Converts the type to a struct |
NSS002 |
Error | Struct doesn't implement ISpecification<T> |
Adds an ISpecification<T> base list entry (prompts for T) |
NSS003 |
Error | Struct isn't declared partial |
Adds the partial modifier |
NSS004 |
Warning | Struct implements ISpecification<T> more than once |
— (flagged for manual split into separate types; see docs/DIAGNOSTICS.md) |
Installation
Reference the main package — the generator ships as an analyzer dependency, no separate install needed:
<PackageReference Include="Nazh.Specifiable" Version="1.2.0" />
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- Microsoft.CodeAnalysis.CSharp (>= 4.9.2)
- Microsoft.CodeAnalysis.Workspaces.Common (>= 4.9.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 125 | 8/2/2026 |