ChildServiceProvider 1.0.0

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

ChildServiceProvider

A small, high‑performance extension for Microsoft.Extensions.DependencyInjection that lets you create child service providers on top of an existing ServiceProvider, overriding or extending registrations while still sharing the same dependency graph.

  • Zero API magic: built on top of IServiceCollection, ServiceProvider, and scopes you already know.
  • Child‑first resolution: child registrations override parent ones (including open generics and keyed services).
  • Scope‑aware: scoped services and lifetimes behave exactly as with the default DI container.
  • Focused: no configuration system, no modules, just child containers.

This library targets net8.0, net9.0 and net10.0 and is designed to be a thin layer over the built‑in DI container.

Getting started

Installation

Add the package from NuGet (package name pending):

dotnet add package ChildServiceProvider

Basic usage

Start with a regular parent ServiceCollection and build a standard ServiceProvider. Then create a ChildServiceCollection that inherits those registrations and build a ChildServiceProvider from it.

using Microsoft.Extensions.DependencyInjection;

var parentServices = new ServiceCollection();
parentServices.AddSingleton<IMyService, ParentService>();

var parentProvider = parentServices.BuildServiceProvider();

// Create child collection based on the parent registrations
var childServices = parentServices.CreateChildServiceCollection();

// Override or add services in the child
childServices.AddSingleton<IMyService, ChildService>();
childServices.AddSingleton<IOtherService, OtherService>();

// Build the child provider
var childProvider = childServices.BuildChildServiceProvider(parentProvider);

// Resolves ChildService from the child provider
var service = childProvider.GetRequiredService<IMyService>();

// Still resolves ParentService from the parent provider
var parentService = parentProvider.GetRequiredService<IMyService>();

Key points:

  • Parent registrations are visible from the child unless overridden.
  • Child registrations never leak back into the parent provider.
  • Transient, scoped and singleton lifetimes behave the same as in the default container.

Concepts

IChildServiceCollection

IChildServiceCollection is a view over two collections:

  • ParentServices: the original parent IServiceCollection.
  • ChildServices: the additional/overriding registrations for the child.

You usually create it from an existing IServiceCollection:

IServiceCollection parentServices = new ServiceCollection();
// ... configure parent ...

IChildServiceCollection childServices = parentServices.CreateChildServiceCollection();

ChildServiceProvider

ChildServiceProvider is an IServiceProvider, IKeyedServiceProvider, and IServiceScopeFactory that delegates to:

  • the parent provider for services not overridden in the child; and
  • the inner provider built from the child collection for overridden registrations.

Resolution rules:

  • Closed types: if a service type is registered in the child, it wins over the parent.
  • Open generics: if the child registers an open generic, it overrides parent closed and open generics for that service type.
  • Keyed services: keyed registrations are treated independently per key; child keyed registrations override parent keyed ones with the same key.

Scopes

ChildServiceProvider fully supports scoping:

  • CreateScope() creates a new scope on both the parent and inner providers.
  • Scoped services resolved from the child behave as in the default container.
  • Cross‑resolution works: a service from the parent can depend on a service registered only in the child and vice versa.

Example:

using var scope = childProvider.CreateScope();
var scoped = scope.ServiceProvider.GetRequiredService<IScopedService>();

Keyed services

On .NET 8+ with the new keyed services APIs, ChildServiceProvider implements IKeyedServiceProvider and understands keys during resolution.

var services = new ServiceCollection();
services.AddKeyedSingleton<IMyService>("parent", (sp, _) => new ParentService());

var parentProvider = services.BuildServiceProvider();
var child = services.CreateChildServiceCollection();
child.AddKeyedSingleton<IMyService>("parent", (sp, _) => new ChildService());

var childProvider = child.BuildChildServiceProvider(parentProvider);

var keyed = ((IKeyedServiceProvider)childProvider)
    .GetRequiredKeyedService(typeof(IMyService), "parent");

In this example, the child keyed registration for key "parent" overrides the parent one.

Benchmarks

This repository includes a small BenchmarkDotNet project under benchmarks/ comparing:

  • default ServiceProvider resolution,
  • ChildServiceProvider with all registrations in the parent,
  • ChildServiceProvider with overrides in the child,
  • mixed scenarios where dependencies live in parent/child.

To run the benchmarks:

cd benchmarks
dotnet run -c Release

Benchmark results depend on your CPU and .NET version. Run them locally to compare behaviors for your own workloads.

Development

Requirements

  • .NET SDK 8.0 or later (project targets net8.0, net9.0, net10.0).

Build and test

From the repository root:

dotnet build

dotnet test

Project structure

  • src/ – main library (ChildServiceProvider, ChildServiceCollection, resolution helpers).
  • tests/ – xUnit test suite covering resolution, scoping, disposal and generics.
  • benchmarks/ – BenchmarkDotNet project to measure performance.

Usage notes

  • Use a ChildServiceProvider when you need per‑tenant or per‑feature overrides without duplicating the entire registration graph.
  • Avoid deep hierarchies of child providers; a small number of layers keeps reasoning about lifetimes simpler.
  • When debugging resolution, it can help to check whether a service is present in the child or only in the parent collection.
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
1.0.0 395 11/20/2025
1.0.0-alpha 389 11/20/2025