簡體   English   中英

Ninject。 將所有接口綁定到單例作用域中的同一類

[英]Ninject. Binding all interfaces to the same class in singleton scope

我希望一個類既可以是一個對象,它提供有關后端的信息,又可以是一個類,后端可以在服務器關閉時通知該類(例如ZooKeeper或WCF)。 問題是當我將同一個類綁定到Singleton范圍內的兩個不同接口時,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使用系統;

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();
            }
        }
    }

因此,我認為在您的模塊中,您將不得不告訴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>());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM