Mapping instance to object in Ninject bindings

.net, c#, ioc-container, ninject

Solution

Take a look at the Custom Scope `.InScope()`. That is exactly what you are looking for.

You provide an instance of an object (your `BindingObject`) to the scope func<>. This object is used as an reference when creating/retrieving instances in the kernel.

The Kernel will check if an instance of `IInner` exists with an reference to that object; If so return instance, otherwise create new.

Example:

Kernel.Bind<IClass>().To<ConcreteClass>();
Kernel.Bind<IInner>().To<ConcreteInner>().InScope(o => { return _binding ; });

var reference1 = new object();
var reference2 = new object();

_binding = reference1;
var class1 = kernel.Get<IClass>();

_binding = reference2;
var class2 = kernel.Get<IClass>();

_binding = reference1;
var class3 = kernel.Get<IClass>();

Here `class1` and `class3` will have the same reference of `IInner`, whereas `class2` will have another reference.

More info at: http://www.ninject.org/wiki.html under Ninject -> Using Ninject -> Object Scopes. Look near the bottom. and an little article about scopes: http://bobcravens.com/2010/03/ninject-life-cycle-management-or-scoping/

//Cheers

Problem

I think this is a relatively straightforward scenario in Ninject but I've been having difficulty finding the right terminology to search for it. I want to do something like: ``` public interface IClass { IInner Inner { get; } } public class ConcreteClass : IClass { public ConcreteClass(IInner inner) { Inner = inner; } public IInner Inner {get; private set;} } public class Test { private BindingObject _binding {get; set;} private override BindingTest() { //These two lines need some extra configuration Kernel.Bind<IClass>().To<ConcreteClass>(); Kernel.Bind<IInner>().To<ConcreteInner>(); _binding = new BindingObject(1); IClass class1 = Kernel.Get<IClass>(); _binding = new BindingObject(2); IClass class2 = Kernel.Get<IClass>(); _binding = new BindingObject(1); IClass class3 = Kernel.Get<IClass>(); //The bindings should be set up such that these asserts both pass Assert.AreSame(class1.Inner, class3.Inner); Assert.AreNotSame(class1.Inner, class2.Inner); } } ``` The implementation of `BindingObject` doesn't matter as this is just a toy example, the idea is just that two `BindingObjects` will compare equal if and only if the `int` passed to their constructor is the same. Likewise, the implementations of `IInner` and `ConcreteInner` don't matter. So essentially the idea is to set up the binding such that `_binding` is used as a key, and every time `Ninject` needs to inject a new `IInner`, it will just return the existing instance if it has one bound to that particular `_binding`, and create a new one if not. Is there some straightforward in-built way to do this? If not, could I get some guidance (not necessarily a full implementation) about an approach?

Original source