Search code examples
c#ninjectnamed-scopeninject-extensions

Proper use of Ninject NamedScope


I´m having a hard time trying to understand how Ninject´s NamedScope module should work. In my mind, each (defined)scope should be used to contextualize bindings that are "InNamedScope".

With this toy example:

void Main()
{
    var kernel = new StandardKernel(new NamedScopeModule(), new ContextPreservationModule());

    kernel.Bind<ParentC>().ToSelf().WithConstructorArgument("name", "Name1").DefinesNamedScope("scope1");
    kernel.Bind<Intf>().ToConstant(new MyC() { ID = 1} ).InNamedScope("scope1");

    kernel.Bind<ParentC>().ToSelf().WithConstructorArgument("name", "Name2").DefinesNamedScope("scope2");
    kernel.Bind<Intf>().ToConstant(new MyC() { ID = 2 }).InNamedScope("scope2");

    kernel.GetAll<ParentC>().Dump();
}


public class Intf
{
    int ID { get; set; }
}


public class MyC : Intf
{
    public int ID { get; set; }
}

public class ParentC
{
    public ParentC(Intf[] c, string name)
    {
        this.C = c;
        Name = name;
    }

    public string Name { get; set; }
    public Intf[] C { get; set; }
}

for me, should yield something like this:

enter image description here

But instead, I get an exeception:

UnknownScopeException: Error activating UserQuery+Intf The scope scope2 is not known in the current context.

what am I missing ?


Solution

  • In Ninject, scope is related to lifetime of objects. I see named scope more as a way of injecting the same instance into different classes, like this:

    public class Parent {
        public Parent(Child child, GrandChild grandChild) {}
    }
    public class Child {
        public Child(GrandChild grandchild) {}
    }
    public class GrandChild {}
    
    kernel.Bind<Parent>().ToSelf().DefinesNamedScope("scope");
    kernel.Bind<GrandChild>().ToSelf().InNamedScope("scope");
    
    kernel.Get<Parent>();
    

    The grandChild injected into Parent is the same instance as is injected into Child.