Wilbert
Wilbert

Reputation: 7399

Injecting the Ninject NamedScope-defining object into its own scope

I have an object that is bound in Ninject like this:

Bind<IScopeRoot>().To<ScopeRoot>()
    .DefinesNamedScope("DemoScope"); 

There are multiple objects in that scope:

Bind<IRootedObject>().To<RootedObject>()
   .InNamedScape("DemoScope");

The problem I run into is that injecting IScopeRoot into a RootedObject will create a new ScopeRoot instance (the root of a new DemoScope) instead of injecting the scope-defining object.

A work-around I used was to create an artificial root object that is nothing but a container for the actual root object, but I feel that is ugly and that it messes up my architecture.

Is there a nice way to inject the scope-defining object into its own scope?

Upvotes: 0

Views: 236

Answers (1)

BatteryBackupUnit
BatteryBackupUnit

Reputation: 13223

Internally Ninject is putting a NamedScopeParameter on the context of the ScopeRoot(=> Binding .DefinesNamedScope).

Warning: I haven't actually compiled any of the following code, but conceptually it should work. Feel free to fix any mistakes i made.

We had the same problem and we used to implement an IScopeRootFactory like that:

internal class ScopeRootFactory : IScopeRootFactory
{
    private readonly IResolutionRoot resolutionRoot;

    public ScopeRootFactory(IResolutionRoot resolutionRoot)
    {
        this.resolutionRoot = resolutionRoot;
    }

    public IScopeRoot CreateScopeRoot()
    {
        return this.resolutionRoot.Get<IScopeRoot>(new NamedScopeParameter("ScopeName");
    }
}

Your bindings will then look like:

Bind<IScopeRootFactory>().To<ScopeRootFactory>();
Bind<IScopeRoot>().To<ScopeRoot>()
    .InNamedScope("ScopeName");
Bind<IRootedObject>().To<RootedObject>()
     .InNamedScope("ScopeName");

Alternative: ToMethod binding

 Bind<ScopeRoot>.ToSelf()
     .InNamedScope("ScopeName");
 Bind<IScopeRoot>()
     .ToMethod(ctx => ctx.Kernel.Get<ScopeRoot>(
           new NamedScopeParameter("ScopeName");
Bind<IRootedObject>().To<RootedObject>()
     .InNamedScope("ScopeName");

Maybe there's also some more elegant way to achieve this.

Upvotes: 1

Related Questions