Ninject Singleton is not injected as Singleton in dependent class

I am creating a class PersonalityConfiguration

that I want to be a singleton and for the most part the Singleton binding works great. Except when this "Singleton" is bound through an interface IPersonalityProvider

in the class constructor. When it is Binding Injected, it is not a Singleton, not the same instance PersonalityConfiguration

, but rather a new instance every time. How do I bind the same Singleton with dependent classes through an interface IPersonalityProvider

?

I have the following definitions of integrity and class

IPersonalityProvider interface

interface IPersonalityProvider
{
    void BeHappy();
}

      

PersonalityConfiguration Class

class PersonalityConfiguration : IPersonalityProvider
{
    private int m_personalityScale = 0;
    public PersonalityConfiguration()
    {
        m_personalityScale = 0;
    }

    public void BeHappy()
    {
        throw new NotImplementedException();
    }
}

      

Classes>

class Person
{
    public Person(IPersonalityProvider personality)
    {
        Personality = personality;
    }

    public IPersonalityProvider Personality { get; set; }
}

      

My Ninject module looks like this

class ProgramNinjectModule : NinjectModule
{
    public override void Load()
    {
        Bind<PersonalityConfiguration>().ToSelf().InSingletonScope();
        Bind<IPersonalityProvider>().To<PersonalityConfiguration>();
    }
}

      

Here is my main

   static void Main(string[] args)
    {
        using (var nKernel = new StandardKernel(new ProgramNinjectModule()))
        {

            //Singleton works here
            PersonalityConfiguration crazy1 = nKernel.Get<PersonalityConfiguration>();  
            PersonalityConfiguration crazy2 = nKernel.Get<PersonalityConfiguration>();  
            Assert.AreEqual(crazy1, crazy2); //True as Expected

            //Expecting PersonalityConfig Singleton to bind to Person1 and 2, does not
            Person person1 = nKernel.Get<Person>();  
            Person person2 = nKernel.Get<Person>();
            Assert.AreEqual(person1.Personality, person2.Personality);  //False, Bombs

            //Obviously this works
            Person person3 = new Person(crazy1);
            Person person4 = new Person(crazy1);
            Assert.AreEqual(person3.Personality, person4.Personality);  //True as Expected
        }

    }

      

+3


source to share


2 answers


The clean way to achieve what you want is with one binding:

Bind<IPersonalityProvider, PersonalityConfiguration>()
    .To<PersonalityConfiguration>()
    .InSingletonScope();

      

this means that whenever ninject is requested to return IPersonalityProvider

or PersonalityConfiguration

, it returns the same (singleton) instance PersonalityConfiguration

.



I have verified that it works correctly using the following code:

using System;
using FluentAssertions;
using Ninject;
using Ninject.Modules;
using Xunit;

namespace NinjectTest.SingletonBoundToMultipleTypes
{
    interface IPersonalityProvider
    {
        void BeHappy();
    }

    class PersonalityConfiguration : IPersonalityProvider
    {
        private int m_personalityScale = 0;
        public PersonalityConfiguration()
        {
            m_personalityScale = 0;
        }

        public void BeHappy()
        {
            throw new NotImplementedException();
        }
    }

    class Person
    {
        public Person(IPersonalityProvider personality)
        {
            Personality = personality;
        }

        public IPersonalityProvider Personality { get; set; }
    }

    class ProgramNinjectModule : NinjectModule
    {
        public override void Load()
        {
            Bind<IPersonalityProvider, PersonalityConfiguration>()
                .To<PersonalityConfiguration>()
                .InSingletonScope();
        }
    }

    public class Test
    {
        [Fact]
        public void PerformTest()
        {
            using (var nKernel = new StandardKernel(new ProgramNinjectModule()))
            {
                //Singleton works here
                PersonalityConfiguration crazy1 = nKernel.Get<PersonalityConfiguration>();
                PersonalityConfiguration crazy2 = nKernel.Get<PersonalityConfiguration>();
                ReferenceEquals(crazy1, crazy2).Should().BeTrue();

                //Expecting PersonalityConfig Singleton to bind to Person1 and 2, does not
                Person person1 = nKernel.Get<Person>();
                Person person2 = nKernel.Get<Person>();
                ReferenceEquals(person1.Personality, person2.Personality)
                    .Should().BeTrue();

                //Obviously this works
                Person person3 = new Person(crazy1);
                Person person4 = new Person(crazy1);
                ReferenceEquals(person3.Personality, person4.Personality)
                    .Should().BeTrue();
            }
        }
    }
}

      

+4


source


Looks like I used the following binding and it worked



class ProgramNinjectModule : NinjectModule
{
    public override void Load()
    {
        Bind<PersonalityConfiguration>().ToSelf().InSingletonScope();
        Bind<IPersonalityProvider>().ToMethod(n => n.Kernel.Get<PersonalityConfiguration>()).WhenInjectedInto<Person>();
    }
}

      

+1


source







All Articles