SourceCrafter.DependencyInjection 2.26.249.144

dotnet add package SourceCrafter.DependencyInjection --version 2.26.249.144
                    
NuGet\Install-Package SourceCrafter.DependencyInjection -Version 2.26.249.144
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SourceCrafter.DependencyInjection" Version="2.26.249.144" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SourceCrafter.DependencyInjection" Version="2.26.249.144" />
                    
Directory.Packages.props
<PackageReference Include="SourceCrafter.DependencyInjection" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SourceCrafter.DependencyInjection --version 2.26.249.144
                    
#r "nuget: SourceCrafter.DependencyInjection, 2.26.249.144"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SourceCrafter.DependencyInjection@2.26.249.144
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SourceCrafter.DependencyInjection&version=2.26.249.144
                    
Install as a Cake Addin
#tool nuget:?package=SourceCrafter.DependencyInjection&version=2.26.249.144
                    
Install as a Cake Tool

SourceCrafter.DependencyInjection

Truly compile-time dependency injection for .NET. Services are declared with attributes and the Roslyn generator emits plain, readable C# resolvers — no reflection, no expression trees, no runtime container.

[ServiceContainer]
[Singleton<IClock, SystemClock>]
[Scoped<DbSession>]
[Transient<Handler>]
public partial class AppContainer { }

using var container = new AppContainer();
var handler = container.CreateScope().Handler;

Full documentation lives in SourceCrafter.DependencyInjection/README.md — attribute reference, generated code walkthrough, cancellation semantics and the SCDI diagnostic table.

Packages

Package What it is
SourceCrafter.DependencyInjection The generator. This is the one you usually want.
SourceCrafter.DependencyInjection.Metadata Attributes only, no generator. For libraries that want to declare contracts without pulling in the generator.
SourceCrafter.DependencyInjection.MsConfiguration The generator plus Microsoft.Extensions.Configuration support ([JsonSetting<T>]). Use instead of the core generator.
SourceCrafter.DependencyInjection.MsConfiguration.Metadata Attributes only, configuration flavour.

Repository layout

  • SourceCrafter.DependencyInjection/ — the generator (netstandard2.0 is deliberately not targeted)
  • SourceCrafter.DependencyInjection.Metadata/ — attribute definitions
  • SourceCrafter.DependencyInjection.MsConfiguration*/ — configuration-aware variants
  • SourceCrafter.DependencyInjection.Tests/ — the test suite
  • Benchmarks/ — BenchmarkDotNet harness

Building and testing

dotnet build SourceCrafter.DependencyInjection.slnx

The test project targets .NET 10 and runs through the xUnit v3 in-process runner. dotnet test is currently unreliable with the .NET 10 SDK here, so run the produced executable directly:

dotnet build SourceCrafter.DependencyInjection.Tests/SourceCrafter.DependencyInjection.Tests.csproj
SourceCrafter.DependencyInjection.Tests/bin/Debug/net10.0/SourceCrafter.DependencyInjection.Tests.exe

Filter with -method "*SomePattern*".

Test layers

Changing the generator means keeping five different kinds of test honest:

  • Tests.cs / Server.cs — behaviour. A realistic container is compiled by the real generator during the build, then exercised at runtime.
  • GeneratedCodeTests.cs — emission. Runs the generator in memory via GeneratorHarness and asserts on the text it produces: lock scoping, the constructor, disposal ordering, file shape, and determinism across repeated passes.
  • RootPropagationTests.cs — the Root/CreateScope virtual-dispatch contract.
  • LockingStrategyTests.cs — the locking scheme itself, modelled by hand with no generator involved. Shows why one lock per lifetime deadlocks on cross-lifetime dependencies, why a single lock is correct but serializing, and why an instance lock cannot guard a static field.
  • EqualityContractTests.cs — guards every generator model type against declaring Equals without a matching ==, which silently breaks incremental caching.

If you touch the emitter, GeneratedCodeTests is where a regression will surface first.

Inspecting generated output

dotnet build -p:EmitCompilerGeneratedFiles=true -p:CompilerGeneratedFilesOutputPath=obj/generated

Emit to a directory outside the project folder, or the generated files get picked up by the next compilation and every type ends up declared twice.

Benchmarks

Benchmarks/ compares this generator against every actively maintained compile-time DI container — Jab, Pure.DI, StrongInject and MrMeeseeks.DIE — following the scenarios that .NET Matrix has made the de facto standard for this category. Results are in the package README.

dotnet run -c Release --project Benchmarks -- --filter "*"

Two rules the harness must keep:

  • Every branch does exactly the same work. An earlier version of this harness only built the container in the SourceCrafter branch while the others created a scope and resolved a service, so the published numbers compared nothing.
  • Hand Coded is the baseline, not another container. Nested new(...) is the floor a compile-time container is trying to reach.

And one rule for reading the output:

  • Do not publish a timing ratio from a single run. These scenarios resolve in tens of nanoseconds, where per-process JIT and heap-layout luck is a large fraction of the measurement. A single-launch run once showed all three containers jumping from ~38 ns to ~80 ns while the baseline held still — three independent libraries do not regress in lockstep. HarnessConfig therefore pins three process launches plus memory randomization, and even then the complex-graph scenario has been seen to vary 0.95x–2.10x across runs of the same binary with byte-identical allocations. Allocation counts are reproducible; sub-100 ns timings are only approximately so.

Where a library genuinely lacks a feature (StrongInject and MrMeeseeks.DIE have no request scope), the row is left empty rather than approximated: a made-up equivalent would measure something no user of that library could write.

Each container declaration lives in its own Containers.*.cs file, because the libraries ship attributes with colliding names ([Transient<,>], [Singleton<,>], [Scoped<,>], [Register]).

Contributing

Issues and pull requests are welcome. A few conventions that are not obvious from the code:

  • The generator project sets EnableDefaultCompileItems=false. Any new .cs file must be added to the .csproj by hand, or it will silently not compile.
  • Parsing and emission are separated on purpose. Anything reachable from a cached delegate must be free of ISymbol, SyntaxNode, SemanticModel and Compilation, otherwise the incremental pipeline keeps whole Roslyn compilations alive. ResolverRenderer is the frozen, symbol-free projection that the emitter renders from.
  • New diagnostics go in ServiceContainerDiagnostics.cs with a fresh, unique SCDI id, and a DiagnosticDescriptor.Title that is static text (dynamic titles break IDE grouping).
  • Generated code is normalized to tabs, CRLF and no trailing whitespace before it is emitted.

License

See LICENSE.txt.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • net10.0

    • No dependencies.

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
2.26.249.144 132 9/6/2026
2.26.233.161 93 8/21/2026
2.26.227.290 99 8/15/2026
2.26.226.430 99 8/14/2026
2.26.226.81 95 8/14/2026
2.26.212.228 107 7/31/2026
2.26.212.105 105 7/31/2026
2.26.211.464 97 7/30/2026
2.26.206.340 104 7/25/2026
2.26.206.240 105 7/25/2026
2.26.206.225 102 7/25/2026
2.26.206.222 104 7/25/2026
2.26.206.28 110 7/25/2026
2.26.206.21 103 7/25/2026
2.26.206.9 105 7/25/2026
2.26.205.341 108 7/24/2026
2.26.205.55 115 7/24/2026
2.26.204.248 111 7/23/2026
2.26.203.271 113 7/22/2026
2.26.203.27 112 7/22/2026
Loading failed