我希望一个类既是一个对象,它提供有关后端的信息,又是一个类,后端在服务器出现故障时通知该类(例如 ZooKeeper 或 WCF)。 问题是,当我将同一个类绑定(bind)到单例范围内的两个不同接口(interface)时,Ninject 会创建两个实例或引发错误,具体取决于我的操作方式。
以下示例必须打印相同的 Guid,并且必须绑定(bind)所有接口(interface)。
示例:
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 使用系统;
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 接口(interface),它也会 IListener 接口(interface):
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 - 也不异常(exception),但应用程序打印不同的 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();
}
}
}
最佳答案
所以我认为在你的模块中你必须告诉 Ninject 这两个接口(interface)正在使用同一个对象。如果不这样做,Ninject 将始终假设每个接口(interface)都有自己的单例。
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>());
}
}
关于c# - 忍者。将所有接口(interface)绑定(bind)到单例范围内的同一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28739091/