External output path (1.1.0) - #2
Merged
Merged
Conversation
A source generator can only add code to the project it runs in, which does not work for Clean Architecture layouts where EF configurations live in Infrastructure but the constants belong in Domain. The generator now also writes the constants to a file in another project, which that project compiles as normal checked-in code. Configured with MSBuild properties, made compiler visible by a targets file shipped in the package: EntityLengthsOutputPath, EntityLengthsOutputNamespace and EntityLengthsEmitInProjectOutput. In-project output is turned off as soon as an output path is set, otherwise the same type would exist in two assemblies. The file is only touched when its content changes, and write failures are reported as ELG0001 instead of throwing out of the generator. Also fixes issues found while reviewing the pipeline: - Options were resolved inside the syntax transform from the Compilation, which is not equatable, so nothing downstream could be cached. Options are now their own equatable pipeline stage and namespace filtering moved to the emit stage. - The pipeline model carried ITypeSymbol, which roots the Compilation and has no value equality. It now carries strings and an EquatableArray. - A DbContext configuring several entities only produced constants for the first one; extractors now return every entity they find. - AttributeExtractor could add the same property twice when both a column type and a StringLength attribute were present. - Entities are no longer silently merged in the dark: colliding simple names report ELG0003 and conflicting lengths report ELG0004. - Records were skipped entirely, and every class in the project went through the semantic model; the predicate now matches classes and records that have a base list or attributed members. - The generator held an options provider in an instance field.
…e sample Package versions move to Directory.Packages.props. EF Core is declared per target framework so multi-targeted projects build against the EF line that matches the framework (8.0.29 / 9.0.18 / 10.0.10) instead of only the newest. Directory.Build.props holds $(SupportedTargetFrameworks) = net8.0;net9.0;net10.0, used by the tests and both samples, so adding a framework is a one-line change. CI installs all three runtimes. The generator itself stays on netstandard2.0, which is what Roslyn loads analyzers from. Adds samples/CleanArchitecture, a three-project sample for the new EntityLengthsOutputPath feature: Domain holds plain entities and the committed Generated/EntityLengths.cs, Infrastructure holds the EF configurations and the output path settings, Api consumes the constants through Domain. Verified that a clean checkout builds in one pass and that the committed file is byte for byte what the generator produces. Two fixes found while wiring this up: - The writer used a fixed "<path>.tmp" temporary file, which collides when the inner builds of a multi-targeted project write the same output in parallel. The temporary name is now unique per write. - Dropped PublishAot from the single-project sample: EF Core is not AOT or trim safe and it only produced IL2026/IL3050 warnings.
The Usage example claimed an output that declared SurnameLength twice, which would not compile, and listed a 200 that no example configured. It is now one entity whose five properties each use a different mechanism, matching the real output including its alphabetical ordering, and a test locks that block so it cannot drift again. The sample output at the end of the README was also missing constants the sample actually generates. Adds a Samples section, a note that conflicting lengths are reported as ELG0004, and a Building this repository section covering central package management and $(SupportedTargetFrameworks). Verifying the README against a real build exposed two defects: - ConstantsSourceBuilder emitted one literal "\r\n" while every other line went through AppendLine, so the file had mixed line endings. For a file that is meant to be committed that means it shows up as permanently modified on another platform. All lines now go through AppendLine, and .gitattributes normalizes the repository. - The parallel inner builds of a multi-targeted project raced on the destination copy, not just the temporary file, and reported a spurious ELG0001. Writes now retry and are accepted when the file already holds the wanted content, which is the normal outcome of that race. Covered by a test that writes the same path from eight threads.
EntityTypeInfo changed shape in this release (ITypeSymbol and List<T> became strings and an EquatableArray, so the model can flow through the incremental pipeline with value equality). It is an implementation detail of the generator, so making it internal now avoids shipping a public type whose shape already broke once. EquatableArray<T> is new in this release and only exists to serve that model, so it becomes internal too. The public surface is now the five types that shipped in 1.0.3, verified by reading the assembly metadata: EntityLengthsGeneratorAttribute EntityMaxLengthGenerator PropertyMaxLength EntityLengthsGeneratorOptions EntityLengthsScanningOptions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.