ServiceCollectionValidation 1.8.0

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

ServiceCollectionValidation

Exactly what it sounds like, validate your service collection.

You can also use ServiceCollectionValidation.AspNetCore to add more validation for AspNetCore projects.

Validate in your Startup.cs

In Startup:

var services = new ServiceCollection();

// hundreds of lines of registration

var validator = Validators.Predefined.Default;
var results = validator.Validate(services);
if (results.Any())
{
    foreach (var result in results)
    {
        Console.WriteLine(result.Message);
    }
    throw new InvalidOperationException("ServiceCollection is not set up correctly.");
}

Validate in your tests

public void ServiceCollectionShouldBeValid()
{
    IServiceCollection services = null!;

    Host
        .CreateDefaultBuilder()
        .ConfigureServices(config =>
        {
            services = config;
        })
        .Build();

  var validator = Validators.Predefined.Default;

  var results = validator.Validate(services);

  results.Should().BeEmpty();
}

Write new rules

You can write your own rules. This one is already defined, but not used by default.

public class ShouldBeInAlphabeticalOrder : IRule
{
    public IEnumerable<Result> Validate(ServiceCollection services)
    {
        var types = services.Select(s => s.ServiceType);
        var firstOutOfOrder = types.Zip(types.OrderBy(t => t.Name)).FirstOrDefault(pair => pair.First != pair.Second);

        return firstOutOfOrder == default
            ? Enumerable.Empty<Result>()
            : [new Result { Message = $"Services should be registered in alphabetical order but found '{firstOutOfOrder.First.Name}' instead of expected '{firstOutOfOrder.Second.Name}'." }];
    }
}

Write new functionality to run before validation

You can write your own functionality to run before validation. One use is to get all the AspNetCore controllers and add them to the service collection to verify them. This is part of the definition from ServiceCollectionValidation.AspNetCore package.

public class ShouldValidateControllers : IRunBeforeValidation
{
    public void RunBeforeValidation(IServiceCollection services)
    {
        foreach (var controller in GetControllers())
        {
            services.TryAddTransient(controller);
        }
    }
    
    // ...
}

Use them with a validator

You can new up your own validator.

var validator = new Validator();
validator.Rules.Add(new ShouldBeInAlphabeticalOrder());

var results = validator.Validate(services);

Or you can create a validator by composing rules, before valitations, and validators using With() and Without().

var validator = Validators.Predefined.Default
  .WithBeforeValidation<CheckCustomServices>()
  .With<ShouldAlwaysImplementAnInterface>()
  .With(new ShouldBeConfiguredFor(CurrentEnvironment));
  .Without<ShouldBeInAlphabeticalOrder>()
  .With(new SuperAdvancedValidator(strict: true));

var results = validator.Validate(services);

Add your own predefined validator

You may want to define what rules to use in one place and reuse them, possibly across projects or repositories. Here's an example of what that might look like in a common business app.

namespace MyCompany.Common;

public static class ValidatorsExtensions
{
    public static Validator MyCompanyValidator(this Validators predefs)
    {
        return predefs.Default
            .With<ShouldBeInAlphabeticalOrder>()
            .With<ShouldBuildAllServices>()
            .With<MyCompany.Common.ShouldFollowOurNamingConventions>()
            .With<MyCompany.Common.ShouldHaveFewerThan50Methods>()
            .With(new MyCompany.Infrastructure.CommonValidator(strict: false));
            // Note: we need this because of bug #1234
            .Without<ShouldNotHaveDuplicates>()
    }
}

Then use it in any projects that reference that extension method.

Validators.Predefined.MyCompanyValidator().Validate(services);

The Default validator is defined like this

public Validator Default = new Validator()
    .With<ShouldNotBeEmpty>()
    .With<ShouldNotHaveDuplicates>()
    .With<ShouldNotCaptureScope>()
    .With<ShouldIncludeAllDependencies>();

Existing rules

ShouldBeInAlphabeticalOrder

Validates types are registererd in alphabeticcal order. Just a silly example.

This is not included in the Default validator.

ShouldBuildAllServices

Validates that all services can actually be built - by actually building them.

This is not included in the Default validator since who knows what side effects building everything might have.

ShouldIncludeAllDependencies

Validates each service has at least one constructor that can be used to instantiate it.

This is included in the Default validator.

ShouldNotBeEmpty

This is included in the Default validator.

ShouldNotCaptureScope

Validates that no services with Scope lifetime are injected into services with the Singleton lifetime.

This is included in the Default validator.

ShouldNotHaveDuplicates

Validates the exact same implementation and service pair aren't registered more than once.

This is included in the Default validator.

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 was computed.  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 was computed.  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 (1)

Showing the top 1 NuGet packages that depend on ServiceCollectionValidation:

Package Downloads
ServiceCollectionValidation.AspNetCore

AspNetCore-specific rules to validate your ServiceCollection.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.8.0 155 2/13/2026
1.7.0 697 12/2/2025
1.6.1 152 11/28/2025
1.6.0 145 11/28/2025
1.5.0 753 9/30/2025
1.4.0 265 9/29/2025
1.3.0 203 9/29/2025
1.2.0 197 9/29/2025
1.1.8 177 9/13/2025
1.1.7 177 9/13/2025
1.1.6 174 9/13/2025
1.1.5 213 8/12/2025
1.1.4 271 8/6/2025
1.1.3 279 8/6/2025