Rokstep.Ninject 0.1.0-alpha

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

Rokstep.Ninject repo

Apache 2.0 License NuGet preview

This repository ships two NuGet packages that together cover the Rokstep migration funnel for the abandoned Ninject DI container:

Package Tier Purpose
Rokstep.Ninject.Shims A — drop-in shim API-compatible replacement for Ninject 3.3.6. Replace one NuGet reference, keep your code, buy time for a real migration. Root namespace Ninject. Every public type [Obsolete] with RKSNI#### IDs.
Rokstep.Ninject B — modern own library A fresh, ergonomic, Rokstep-branded DI container for .NET 8+. Not API-compatible with Ninject. Fluent Register<T>().To<TImpl>().Singleton() DSL, IAsyncDisposable support, immutable state-machine builder. Built on Microsoft.Extensions.DependencyInjection 8.0.x internally in v0.1; the stable public API is the runway for an Expression-tree backend (v0.2) and a NativeAOT source generator (v0.3). See docs/ninject-shims-design.md.

Use Tier A first if you have legacy Ninject code you cannot afford to rewrite. Move to Tier B when you are ready to modernize but would rather not write every registration against raw Microsoft.Extensions.DependencyInjection. Go straight to MEDI (Tier C) if portability matters more than ergonomics.

Rokstep.Ninject.Shims (Tier A — drop-in shim for Ninject)

Why this exists

Ninject's last stable release (3.3.6) shipped in May 2022. The project has not seen meaningful development since — no security fixes, no .NET 9 / 10 / 11 compatibility guarantees. Applications using Ninject face a choice:

  1. Stay on Ninject, risk breakage on future .NET.
  2. Rewrite every binding to Microsoft.Extensions.DependencyInjection. Days to weeks of work for a medium codebase, high risk of regressions.
  3. Use Rokstep.Ninject.Shims. Replace one NuGet reference, keep existing code. Done in minutes.

Rokstep.Ninject.Shims is option 3. It is an independent reimplementation of Ninject's public API surface, powered internally by Microsoft.Extensions.DependencyInjection. It is not a fork, not an official successor, and not endorsed by the Ninject project. It exists to keep your existing code working while you plan a real migration at your own pace.

Installation

dotnet remove package Ninject
dotnet add package Rokstep.Ninject.Shims --version 0.1.0-alpha

Quick start

using Ninject;
using Ninject.Modules;

#pragma warning disable CS0618 // Accept the migration hints, address them gradually.

var kernel = new StandardKernel(new WarriorModule());
var samurai = kernel.Get<Samurai>();
samurai.Attack("imaginary goblin");

public interface IWeapon { void Hit(string target); }
public sealed class Sword : IWeapon { public void Hit(string target) => Console.WriteLine($"Sword strikes {target}."); }
public sealed class Samurai(IWeapon weapon) { public void Attack(string target) => weapon.Hit(target); }

public sealed class WarriorModule : NinjectModule
{
    public override void Load()
    {
        Bind<IWeapon>().To<Sword>();
        Bind<Samurai>().ToSelf();
    }
}

Output: Sword strikes imaginary goblin.

Nothing above is Rokstep-specific. It's the canonical Ninject Samurai example, paraphrased. The same code compiled against the original Ninject 3.3.6 produces the same result.

What's in v0.1.0-alpha

API Status Notes
StandardKernel Default constructor + params INinjectModule[] + IEnumerable<INinjectModule> overloads
IKernel Full interface including IServiceProvider
Bind<T>().To<TImpl>() Core binding
Bind<T>().ToSelf() Self-binding
Bind<T>().ToConstant(value) Singleton instance
Bind<T>().ToMethod(Func<IContext, T>) Factory method
InSingletonScope() Maps to ServiceLifetime.Singleton
InTransientScope() Maps to ServiceLifetime.Transient
Unbind<T>(), Rebind<T>() Binding removal and replacement
NinjectModule base class Full module registration flow
Get<T>(), Get(Type), TryGet<T>() Resolution extension methods
ActivationException Thrown on resolve failure, matching Ninject's message format
Constructor injection Delegates to MEDI's automatic constructor selection
HasModule(string) Uses Type.FullName to match Ninject's default
Named bindings .Named("foo") deferred to v0.2
Conditional bindings .When(...) deferred to v0.2
Custom scopes Only Singleton and Transient in v0.1
Ninject.Web., Ninject.Extensions. Separate packages, future work

See docs/api-surface.md for the full v0.1 plan, including should-have and nice-to-have tiers.

Proven drop-in compatibility

The test suite includes parity tests: the same scenarios run against both the original Ninject 3.3.6 and Rokstep.Ninject.Shims via extern alias, asserting identical behavior. 8 parity scenarios currently pass on net8.0, covering:

  • Bind → Get produces the same implementation type
  • Singleton scope returns the same instance on both
  • Transient scope returns distinct instances on both
  • Rebind replaces existing binding
  • Module load registers bindings
  • Missing binding throws ActivationException on both
  • ToConstant binds a specific instance
  • HasModule resolves by Type.FullName (bug parity with original)

This is stronger evidence than a traditional test suite because it tests your shim against the thing it replaces in the same process.

See docs/compatibility-matrix.md for results on external open source projects (future work).

Migration path

Rokstep.Ninject.Shims is a transitional package. Every public type carries an [Obsolete] attribute with a DiagnosticId of the form RKSNI####, pointing to migration documentation. The recommended path:

  1. Install Rokstep.Ninject.Shims today. Zero code changes. Your existing Ninject code compiles and runs on .NET 6/8.
  2. Install Rokstep.Analyzers (companion package). Enables IDE-level diagnostics and code fixes for all RKSNI rules.
  3. Gradually migrate to one of:
    • Rokstep.Ninject (Tier B) — a modern, fluent, Rokstep-branded DI container for .NET 8+. Ships in this repository alongside the shim at v0.1.0-alpha. Uses records, immutable state-machine builders, and IAsyncDisposable. Not API-compatible with Ninject, but brand-consistent and designed for long-term stability.
    • Microsoft.Extensions.DependencyInjection (Tier C) — fully standard. The analyzer's code fixes prefer this path for maximum portability.

The shim's job is to buy you time. Use it wisely.

Limitations and known differences

Scenario Behavior Notes
IKernel.Release(object) No-op Ninject historically tied instance lifetime to activation scope. MEDI scopes by container, so there's no direct equivalent. Documented in docs/known-quirks.md.
Rich IContext in ToMethod Minimal Only ServiceType and Kernel populated. Users inspecting context.Request, context.Binding, etc. get defaults.
.Named(...), .When(...) Not implemented Fluent DSL includes the stubs but does nothing. Planned for v0.2.
Custom KernelBase subclassing Not supported StandardKernel is sealed. Write bindings via modules or extension methods.

License

Licensed under the Apache License 2.0.

Attribution

Rokstep.Ninject.Shims is an independent drop-in replacement for Ninject, which is itself licensed under Apache 2.0 / Microsoft Public License (dual). Portions of the public API surface are derived from Ninject's public API — Copyright 2007-2010 Enkari, Ltd. and 2010-2020 Ninject Project Contributors. No Ninject source code was copied; all implementations are original.

"Ninject" is used solely to identify the original library this shim replaces. Rokstep is not affiliated with or endorsed by the Ninject Project Contributors.

Rokstep.Ninject (Tier B — modern Rokstep DI container)

A fresh, ergonomic DI container that ships alongside the shim. Not API-compatible with Ninject, not a drop-in replacement. Built on top of Microsoft.Extensions.DependencyInjection 8.0.x internally for v0.1 — the public surface is deliberately stable so the backend can evolve (Expression trees, NativeAOT-friendly source generators) without breaking callers.

Installation

dotnet add package Rokstep.Ninject --version 0.1.0-alpha

Target framework: net8.0 only for v0.1.

Quick start

using Rokstep.Ninject;

using RokstepContainer container = RokstepContainer.Create(builder =>
{
    builder.Register<IGreeter>().To<ConsoleGreeter>().Singleton();
    builder.Register<Clock>().ToInstance(new Clock(DateTimeOffset.UtcNow));
});

IGreeter greeter = container.Resolve<IGreeter>();
greeter.Greet("world");

public interface IGreeter { void Greet(string name); }
public sealed class ConsoleGreeter : IGreeter
{
    public void Greet(string name) => Console.WriteLine($"Rokstep.Ninject says: Hello, {name}!");
}
public sealed record Clock(DateTimeOffset Now);

Output: Rokstep.Ninject says: Hello, world!

What's in v0.1.0-alpha

API Status Notes
RokstepContainer.Create(Action<ContainerBuilder>) Yes Static entry point, no new ceremony
Register<T>().To<TImpl>() Yes Core binding
Register<T>().ToInstance(value) Yes Pre-constructed singleton
Register<T>().ToFactory(sp => ...) Yes Factory binding with provider access
.Singleton(), .Scoped(), .Transient() Yes Fluent lifetime selection
Resolve<T>(), Resolve(Type) Yes Generic + non-generic resolution
ResolveAsync<T>(ct) Yes Stable async shape; synchronous under the hood in v0.1
CreateScope() Yes Returns an IServiceScope with the correct scoped-lifetime semantics
IAsyncDisposable + IDisposable Yes DisposeAsync honors async-disposable singletons
Multi-target No net8.0 only for v0.1
Decorator DSL No Deferred to v0.2
Conditional / keyed bindings No Deferred to v0.2
Expression-tree backend No Deferred to v0.2
NativeAOT / source generator No Deferred to v0.3

See docs/ninject-shims-design.md for the full design rationale and future roadmap.

When to choose Rokstep.Ninject vs. alternatives

  • Choose Rokstep.Ninject (Tier B) if you are ready to modernize off the shim, want a fluent API that reads better than raw MEDI, and want to defer the choice of resolver internals to a library you can upgrade later.
  • Choose Microsoft.Extensions.DependencyInjection (Tier C) if portability matters more and you are happy to write registrations against IServiceCollection extensions.
  • Choose Rokstep.Ninject.Shims (Tier A) if you still have legacy Ninject bindings you cannot afford to rewrite today.
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

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.1.0-alpha 88 4/17/2026