我正在创建一个PersonalityConfiguration
类,我想成为一个Singleton,而且大多数情况下Singleton绑定工作正常。除了这个" Singleton"通过类的构造函数中的IPersonalityProvider
接口绑定。当Binding被注入时,它不是Singleton,不是PersonalityConfiguration
的相同实例,而是每次都是一个新实例。如何通过IPersonalityProvider
接口将相同的Singleton绑定到依赖类?
我有以下的Inteface和Class Definitions
接口IPersonalityProvider
interface IPersonalityProvider
{
void BeHappy();
}
Class PersonalityConfiguration
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; }
}
我的Ninject模块如下
class ProgramNinjectModule : NinjectModule
{
public override void Load()
{
Bind<PersonalityConfiguration>().ToSelf().InSingletonScope();
Bind<IPersonalityProvider>().To<PersonalityConfiguration>();
}
}
这是我的主要
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
}
}
答案 0 :(得分:4)
通过单一绑定实现您想要的干净方式:
Bind<IPersonalityProvider, PersonalityConfiguration>()
.To<PersonalityConfiguration>()
.InSingletonScope();
这意味着只要请求ninject返回IPersonalityProvider
或 PersonalityConfiguration
,它就会返回PersonalityConfiguration
的相同(单例)实例。
我已使用以下代码验证它是否正常工作:
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();
}
}
}
}
答案 1 :(得分:1)
看起来我使用了以下绑定并且工作正常
class ProgramNinjectModule : NinjectModule
{
public override void Load()
{
Bind<PersonalityConfiguration>().ToSelf().InSingletonScope();
Bind<IPersonalityProvider>().ToMethod(n => n.Kernel.Get<PersonalityConfiguration>()).WhenInjectedInto<Person>();
}
}