0

The title has it all. When I do this:

var kernel = new StandardKernel();
kernel.Bind<IMyClass>().To<MyClass>().InSingletonScope();
var myClass = kernel.Get<IMyClass>();

Where is the instance of MyClass stored? Is it stored in a static dictionary somewhere globally? Or is it stored in the kernel instance?

For example if I do this:

var kernel1 = new StandardKernel();
var kernel2 = new StandardKernel();
kernel1.Bind<IMyClass>().To<MyClass>().InSingletonScope();
kernel2.Bind<IMyClass>().To<MyClass>().InSingletonScope();
var myClass1 = kernel1.Get<IMyClass>();
var myClass2 = kernel2.Get<IMyClass>();

Will myClass1 be the same instance as myClass2 or will they be different instances.

To kind of jump on an inevitable question "Why do you need to do that?": It doesn't matter. That is not the point of the question. I have my reasons and just want to know how this piece works.

computrius
  • 690
  • 7
  • 16

2 Answers2

2

So Ninject stores them here:

  /// <summary>Tracks instances for re-use in certain scopes.</summary>
  public class Cache : NinjectComponent, ICache, INinjectComponent, IDisposable, IPruneable
  {
    /// <summary>
    /// Contains all cached instances.
    /// This is a dictionary of scopes to a multimap for bindings to cache entries.
    /// </summary>
    private readonly IDictionary<object, Multimap<IBindingConfiguration, Cache.CacheEntry>> entries = (IDictionary<object, Multimap<IBindingConfiguration, Cache.CacheEntry>>) new Dictionary<object, Multimap<IBindingConfiguration, Cache.CacheEntry>>((IEqualityComparer<object>) new WeakReferenceEqualityComparer());
...

and Cache is scoped to instance of a kernel.

Will myClass1 be the same instance as myClass2 or will they be different instances.

Different. Cache is not static.

Jan Muncinsky
  • 4,282
  • 4
  • 22
  • 40
  • I ran some tests at the suggestion of juharr (see comment in original question), and those tests indicate different. I used the same code as above in my question and then did a test to see if "myClass1 == myClass2". They were in fact the same instance. – computrius Nov 15 '17 at 19:51
  • 2
    @computrius I ran the same test and obtained two different instances, which is the expected behaviour. Note that the code posted above comes from Ninject sources https://github.com/ninject/Ninject/blob/5a40fd013ab39b8118ab4c413e5c2ab9414729e9/src/Ninject/Activation/Caching/Cache.cs#L41 – jbl Nov 16 '17 at 08:29
  • 1
    @computrius Probably your test code was flawed. Possible issue: do the types override the Equals method? Different kernel instances will create different singleton instances. – BatteryBackupUnit Nov 16 '17 at 09:11
  • Ran it again and it seems I was mistaken. Marking this as the answer. – computrius Nov 16 '17 at 15:00
-2

For others that are wondering: It stores it outside of the kernel. You will get the same instance with both kernels.

Edit - Test I ran to come to this conclusion:

var kernel1 = new StandardKernel();
var kernel2 = new StandardKernel();
kernel1.Bind<IMyClass>().To<MyClass>().InSingletonScope();
kernel2.Bind<IMyClass>().To<MyClass>().InSingletonScope();
var myClass1 = kernel1.Get<IMyClass>();
var myClass2 = kernel2.Get<IMyClass>();
var same = myClass1 == myClass2;
Console.WriteLine(same ? "Same" : "Different");

Output: Same

Edit Again: I must have had a typo because I tested again and got "Different".

computrius
  • 690
  • 7
  • 16
  • Not sure why this was downvoted, because my tests indicate it was in fact correct. I edited the answer with the test I ran. Unless the discrepancy can be explained to me, it will be the accepted answer in two days.. – computrius Nov 15 '17 at 19:54
  • 4
    I don't think it will be the same. Try `object.ReferenceEquals` method to test for reference equality. Maybe your `MyClass` class overrides the `==` operator? – Yacoub Massad Nov 15 '17 at 22:52
  • It was downvoted, because it's not true. There is no other reason why it should return "Same" apart of what was already mentioned by Yacoub. – Jan Muncinsky Nov 16 '17 at 09:03
  • also, you should publish the complete code necessary for the test. The definitions and implementations for the interfaces/class are missing. – BatteryBackupUnit Nov 16 '17 at 09:13
  • Interesting, it is different with referenceequals. So then, what is the difference? I just tested with a base class with no overloading configured for "==". My understanding is that the only reason for myClass.Equals(...) is that == will compare the reference and not the content. Is this not the case? Maybe I just had a typo and overlooked it. – computrius Nov 16 '17 at 14:59
  • @computrius As the developer is free to override the equals method, there is no guarantee it actually performs a reference equality check. Hence the need for `ReferenceEquals` - no one can mess with that! – BatteryBackupUnit Nov 22 '17 at 11:32
  • @BatteryBackupUnit Sure, I know that. But this was a small test class that I wrote myself that did not. I must have just been mistaken about the result. – computrius Nov 27 '17 at 15:12