ZCrew.Extensions.DependencyInjection.Registration 3.0.1

dotnet add package ZCrew.Extensions.DependencyInjection.Registration --version 3.0.1
                    
NuGet\Install-Package ZCrew.Extensions.DependencyInjection.Registration -Version 3.0.1
                    
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="ZCrew.Extensions.DependencyInjection.Registration" Version="3.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ZCrew.Extensions.DependencyInjection.Registration" Version="3.0.1" />
                    
Directory.Packages.props
<PackageReference Include="ZCrew.Extensions.DependencyInjection.Registration" />
                    
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 ZCrew.Extensions.DependencyInjection.Registration --version 3.0.1
                    
#r "nuget: ZCrew.Extensions.DependencyInjection.Registration, 3.0.1"
                    
#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 ZCrew.Extensions.DependencyInjection.Registration@3.0.1
                    
#: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=ZCrew.Extensions.DependencyInjection.Registration&version=3.0.1
                    
Install as a Cake Addin
#tool nuget:?package=ZCrew.Extensions.DependencyInjection.Registration&version=3.0.1
                    
Install as a Cake Tool

ZCrew.Extensions.DependencyInjection.Registration

Convention-based service registration for Microsoft.Extensions.DependencyInjection, modelled on Castle Windsor's registration API. Scan assemblies, filter types, and register the lot through a fluent chain.

One-page reference: the registration cheat sheet. Every entry point, filter, selector, keyed overload and lifetime helper in one place, plus recipes you can paste. The fastest way to find the method you're after.

What you get

  • Assembly scanning. Scan whole assemblies, or hand it an explicit list of types
  • Type filters. By base type (BasedOn), namespace (InNamespace) or your own predicate (Where)
  • Service mapping. Register as an interface (AsInterface), every interface (AsAllInterfaces), the type itself (AsSelf), the base type (AsBase), or whatever your delegate says. Chain selectors to combine them, like AsSelf().AsAllInterfaces()
  • Naming conventions. AsDefaultInterfaces matches types to interfaces by name, so OrderService goes to IOrderService
  • Keyed services. Set keys directly, work them out from the names, or use your own selector
  • Visibility control. Include or skip internal types when scanning

Installation

dotnet add package ZCrew.Extensions.DependencyInjection.Registration

or in your .csproj:

<ItemGroup>
  <PackageReference Include="ZCrew.Extensions.DependencyInjection.Registration" Version="3.0.0" />
</ItemGroup>

That single reference brings both the runtime API and the [Service] source generator. The generator ships inside the package as an analyzer, so NuGet wires it into the compiler for you: no second package, and none of the OutputItemType="Analyzer" or PrivateAssets="all" wiring you'd write to pull a generator in from a project reference.

Quick start

Register every repository in the current assembly:

services.AddSingleton(
    Classes.FromThisAssembly()
        .BasedOn<IRepository>()
        .AsInterface()
);

Register services by naming convention, so OrderService registers as IOrderService:

services.AddSingleton(
    Classes.FromThisAssembly()
        .InNamespace("MyApp.Services")
        .AsDefaultInterfaces()
);

The chain

Each step narrows or transforms what gets registered:

Entry point → Type filtering → Service selection → Keyed selection → Lifetime → Terminal
services.AddSingleton(
    Classes.FromThisAssembly()          // scan the calling assembly
        .IncludeInternalTypes()         // internal types too (optional)
        .BasedOn<IHandler>()            // only IHandler implementations
        .Where(t => !t.IsNested)        // and not nested ones
        .AsInterface()                  // register each as its IHandler interface
        .Keyed()                        // keys worked out from the type names
);

Entry points

Method Where types come from
Classes.FromThisAssembly() Concrete classes in the calling assembly
Classes.FromAssembly(assembly) Concrete classes in a specific assembly
Classes.From(types) Concrete classes from a list you provide
Types.FromThisAssembly() All types (interfaces, structs, etc.) in the calling assembly

Service mapping

Selectors return a ServiceSelector, so you can chain them. AsSelf().AsAllInterfaces() registers the union of both.

Method Registers as
AsInterface() Top-level interfaces deriving from the BasedOn type
AsAllInterfaces() Every interface implemented
AsDefaultInterfaces() Interfaces matching by name
AsSelf() The implementation type
AsBase() The BasedOn base types
As(selector) Whatever your delegate returns

Keyed services

// Work the key out from the names (PayPalGateway → key "PayPal" for IPaymentGateway)
.Keyed()

// One key for everything
.Keyed("myKey")

// Your own selector
.Keyed(implType => implType.Name)

Compile-time [Service] registration

The package also bundles a source generator as an analyzer, so there's nothing extra to install. Annotate a type with [Service] and it's collected at compile time into an assembly-local Services.FromThisAssembly() (a ServiceFilter), with no reflection at startup:

using Microsoft.Extensions.DependencyInjection;
using ZCrew.Extensions.DependencyInjection.Registration;

[Service, Scoped, As<IEmailSender>]
public class Emailer : IEmailSender;

// then, in the same assembly:
services.Add(Services.FromThisAssembly());                          // everything
services.Add(Services.FromThisAssembly().BasedOn<IEmailSender>());  // or narrow it down first

See Compile-time registration with [Service] for the rest of the attributes ([As<T>], [Singleton] / [Scoped] / [Transient], [Keyed]), what they do, and the ZCDI001 to ZCDI004 diagnostics.

Trimming and native AOT

The package is marked IsAotCompatible, but only the compile-time path is trim-safe:

Path Trimming and AOT
[Service] + Services.FromThisAssembly() ✅ Safe. The registrations are baked in at compile time.
Service.From<T>() / Service.From(typeof(T)) ✅ Safe. The implementation keeps its constructors and interfaces.
Classes / Types assembly scanning ⚠️ Not supported. The entry points are [RequiresUnreferencedCode].

Assembly scanning can't be made trim-safe. The trimmer removes unreferenced types before the scan runs, so services would quietly vanish from the container. Rather than let that fail at runtime, every Classes and Types entry point warns at compile time (one IL2026 per chain) and points you at the generator. If you publish trimmed or AOT, use [Service].

One thing that's out of this package's hands: registering open generic service types goes through MakeGenericType, which Microsoft's container can't make AOT-safe.

Full API reference

The summaries above cover the common cases. For every method, overload and recipe on one page, see the registration cheat sheet. The longer guides live in the docs folder.

License

MIT. See LICENSE.md.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
3.0.1 111 8/21/2026
3.0.0 130 8/3/2026
3.0.0-preview.2 72 7/19/2026
3.0.0-preview.1 73 7/15/2026
2.0.0 116 5/23/2026
1.1.0 123 3/25/2026
1.0.1 120 3/19/2026
1.0.0 116 3/19/2026
1.0.0-preview.1 82 2/22/2026