SsalKit.DependencyInjection 0.0.1

There is a newer version of this package available.
See the version list below for details.
dotnet add package SsalKit.DependencyInjection --version 0.0.1
                    
NuGet\Install-Package SsalKit.DependencyInjection -Version 0.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="SsalKit.DependencyInjection" Version="0.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SsalKit.DependencyInjection" Version="0.0.1" />
                    
Directory.Packages.props
<PackageReference Include="SsalKit.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 SsalKit.DependencyInjection --version 0.0.1
                    
#r "nuget: SsalKit.DependencyInjection, 0.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 SsalKit.DependencyInjection@0.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=SsalKit.DependencyInjection&version=0.0.1
                    
Install as a Cake Addin
#tool nuget:?package=SsalKit.DependencyInjection&version=0.0.1
                    
Install as a Cake Tool

← SsalKit

English | 한국어 | 日本語

SsalKit.DependencyInjection

Compile-time DI auto-registration for .NET, powered by a Roslyn source generator — no reflection, no assembly scanning, no runtime cost. NuGet

Why SsalKit.DependencyInjection?

Most "automatic" DI registration libraries work by scanning loaded assemblies with reflection at startup. That approach has real costs: startup latency that grows with your assembly count, metadata that trimming and Native AOT can't reason about, and failures that only surface at runtime.

SsalKit.DependencyInjection takes a different approach:

  • Compile-time, not runtime. A source generator inspects your code during the build and emits the registration calls directly as C# — there is no scanning step to run when your app starts.
  • Zero reflection. The generated code is a plain, readable IServiceCollection extension method. Nothing is discovered dynamically.
  • AOT & trimming friendly. Because registrations are ordinary generated code rather than reflection-driven discovery, they survive trimming and Native AOT compilation without extra annotations.
  • Compile-time diagnostics. Mistakes like registering an abstract class or an unimplemented interface are caught by the compiler, not by a runtime exception in production.

Installation

dotnet add package SsalKit.DependencyInjection

The package contains both the [Service] attribute and the source generator — no separate analyzer package to install.

Quick Start

Decorate the classes you want registered:

using Microsoft.Extensions.DependencyInjection;
using SsalKit.DependencyInjection;

// Registered under every interface it implements (or itself, if it implements none).
[Service(ServiceLifetime.Singleton)]
public class CacheService : ICacheService { }

// Registered only as the given type.
[Service(ServiceLifetime.Scoped, As = typeof(IUserRepository))]
public class UserRepository : IUserRepository, IDisposable { }

// Defaults to ServiceLifetime.Singleton.
[Service]
public class EmailSender { }

// Registered as a keyed service (.NET 8+ keyed DI).
[Service(ServiceLifetime.Singleton, Key = "redis")]
public class RedisCache : ICache { }

// Only registered if IClock hasn't already been registered.
[Service(ServiceLifetime.Singleton, Mode = RegistrationMode.TryAdd)]
public class DefaultClock : IClock { }

At build time, the generator emits one extension method per assembly, named after the assembly itself. For example, an assembly called MyApp.Web gets AddMyAppWebServices(), roughly equivalent to:

// <auto-generated/>
namespace Microsoft.Extensions.DependencyInjection;

public static class MyAppWebServiceCollectionExtensions
{
    public static IServiceCollection AddMyAppWebServices(this IServiceCollection services)
    {
        services.AddSingleton<CacheService>();
        services.AddSingleton<ICacheService>(sp => sp.GetRequiredService<CacheService>());

        services.AddScoped<IUserRepository, UserRepository>();

        services.AddSingleton<EmailSender>();

        services.AddKeyedSingleton<ICache, RedisCache>("redis");

        services.TryAddSingleton<IClock, DefaultClock>();

        return services;
    }
}

Wire it up in Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMyAppWebServices();

var app = builder.Build();

Multi-interface Singleton/Scoped registrations are generated as a concrete registration plus factory forwarding, so every interface resolves to the same shared instance.

Attribute Reference

[Service(lifetime, As = ..., Mode = ..., Key = ...)]

Property Type Default Description
Lifetime ServiceLifetime ServiceLifetime.Singleton Constructor argument. Singleton, Scoped, or Transient.
As Type? null Registers only as this type instead of every implemented interface (or itself).
Mode RegistrationMode RegistrationMode.Add Add, TryAdd, TryAddEnumerable, or Replace — how the call is applied to the collection.
Key object? null Registers as a keyed service (.NET 8+) using AddKeyed* instead of Add*.

A class can carry multiple [Service] attributes to register it several ways (different lifetimes, As targets, or keys) at once.

Diagnostics

The generator validates your [Service] usage at compile time:

ID Severity Description
SSAL001 Error [Service] was applied to an abstract or static class.
SSAL002 Error The type specified in As is not implemented by the decorated class.
SSAL003 Error Open generic types are not supported.
SSAL004 Warning The same service registration appears to be duplicated.
SSAL005 Error Key was combined with RegistrationMode.TryAddEnumerable, which is not a supported combination.

License

MIT — see LICENSE.


AI disclosure: This project was built with AI assistance (Claude).

Product Compatible and additional computed target framework versions.
.NET 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
0.0.6 121 8/9/2026
0.0.5 118 7/31/2026
0.0.4 118 7/26/2026
0.0.3 111 7/25/2026
0.0.2 119 7/24/2026
0.0.1 120 7/20/2026