c# - 忍者。将所有接口(interface)绑定(bind)到单例范围内的同一个类

标签 c# dependency-injection singleton ninject

我希望一个类既是一个对象,它提供有关后端的信息,又是一个类,后端在服务器出现故障时通知该类(例如 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/

相关文章:

java - 单例 EJB 中的系统异常

python - pythontwisted中动态广播配置变化

c# - SqlBulkCopy 错误处理/错误继续

javascript - 如何显示来自代码隐藏的警报消息?

c# - 依赖注入(inject)和 C# 中的 Guard 子句和空对象模式

java - 是否强制/推荐使用 requireExplicitBindings

c# - MEF 和 MVVM - 添加约定的方式?

c# - 如何在c#中制作自定义进度条

c# - 对在Docker容器上运行的C#dot net应用程序进行性能分析

java - 在 getInstance() 方法或实例变量定义中初始化单例之间是否存在功能差异