我希望一个类既是一个提供有关后端信息的对象,另一个是后端在服务器关闭时通知的类(例如ZooKeeper或WCF)。 问题是当我将同一个类绑定到单例范围内的两个不同接口时,Ninject会创建两个实例或引发错误,具体取决于我的操作方式。
以下示例必须打印相同的Guid,并且必须绑定所有接口。
示例:
Program.cs的
using System;
using Ninject;
using Ninject.Modules;
namespace ConsoleApplication1
{
static class Program
{
static void Main(string[] args)
{
IKernel kernel = new StandardKernel();
kernel.Load(new INinjectModule[] { new Bindings() });
Console.WriteLine("First interface");
var i1 = kernel.Get<IState>();
i1.Inform();
Console.WriteLine("Second interface");
var i2 = kernel.Get<IListener>();
i2.Send();
Console.ReadKey();
}
}
}
IListener.cs
namespace ConsoleApplication1
{
public interface IListener
{
void Send();
}
}
IState.cs
namespace ConsoleApplication1
{
public interface IState
{
void Inform();
}
}
StateClass.cs 使用System;
namespace ConsoleApplication1
{
public class StateClass : IState, IListener
{
private readonly String _seed;
public StateClass()
{
_seed = Guid.NewGuid().ToString();
}
public void Send()
{
Console.WriteLine(_seed);
}
public void Inform()
{
Console.WriteLine(_seed);
}
}
}
Bindings.cs - 版本1 在此示例中,如果代码已注释,则一切正常。问题是我事先不知道如果一个类强迫 IState 接口它还会 IListener 接口:
using Ninject.Modules;
using Ninject.Extensions.Conventions;
namespace ConsoleApplication1
{
class Bindings : NinjectModule
{
public override void Load()
{
Kernel.Bind(x => x
.FromAssemblyContaining<IState>()
.SelectAllClasses()
.InheritedFrom<IState>()
.BindAllInterfaces()
.Configure(y => y.InSingletonScope()));
//uncomment the following binding to see an exception
//problem is we dont know this in advance
//Kernel.Bind(x => x
// .FromAssemblyContaining<IListener>()
// .SelectAllClasses()
// .InheritedFrom<IListener>()
// .BindAllInterfaces()
// .Configure(y => y.InSingletonScope()));
}
}
}
Bindings.cs - 版本2 - 没有例外,但是应用程序会打印不同的Guid:
using Ninject.Modules;
using Ninject.Extensions.Conventions;
namespace ConsoleApplication1
{
class Bindings : NinjectModule
{
public override void Load()
{
Kernel.Bind<IListener>().To<StateClass>().InSingletonScope();
Kernel.Bind<IState>().To<StateClass>().InSingletonScope();
}
}
}
答案 0 :(得分:2)
所以我认为在你的模块中你必须告诉Ninject两个接口都使用相同的对象。如果你不这样做,Ninject将始终假设每个接口都有自己的单例。
class Bindings : NinjectModule
{
public override void Load()
{
Kernel.Bind<StateClass>().ToSelf().InSingletonScope();
Kernel.Bind<IListener>().ToMethod(ctx => ctx.Kernel.Get<StateClass>());
Kernel.Bind<IState>().ToMethod(ctx => ctx.Kernel.Get<StateClass>());
}
}