如何设置Ninject单身人士

时间:2014-02-11 15:46:22

标签: c# singleton ninject

我有一个类(MyFacade)我用Ninject注入了参数:

class MyFacade
{
    IDemoInterface demo;

    public MyFacade(IDemoInterface demo)
    {
        this.demo = demo;
    }

    public void MyMethod()
    {
        Console.WriteLine(demo.GetInfo());
    }
} 

当然,我必须设置Ninject以注入适当的参数实现(IDemoInterface

我知道,我可以通过MyFacade实例化kernel.Get<MyFacade>();对象而不设置任何其他内容。目前我的门面没有接口(因为它是我唯一的实现,也许我会为标准建议添加其接口)

如果我想制作这个外观singlenton,我知道两种方法:创建一个空构造函数并通过执行此kernel.Get<IDemoInterface>();或通过设置Ninject传递参数:kernel.Bind<MyFacade>().To<MyFacade>().InSingletonScope();

第二个看起来更好的方法,但你知道以单一方式设置它的任何其他方法吗?

2 个答案:

答案 0 :(得分:25)

设置绑定时,需要绑定依赖项。在绑定中设置依赖项总是更好,而不是在构造函数中执行kernel.Get<T>()。您正在使用IOC,因此请利用您正在使用的框架为您进行注射。

在第二个示例绑定中,您缺少的是IDemoInterface中的绑定。您的绑定应如下所示:

//bind the dependency to the implementation.
kernel.Bind<IDemoInterface>().To<DemoInterface>();
//since you bound your dependency, ninject should now have 
// all the dependencies required to instantiate your `MyFacade` object.
kernel.Bind<MyFacade>.To<MyFacade>().InSingletonScope(); 

答案 1 :(得分:5)

如果您不希望容器使用InSingletonScope()管理单件的生命周期,但仍希望它被注入,我可以想到两种方法。选择哪一种更适合您的需求。请考虑以下ISingleton(命名您的界面)实现:

public class ConcreteSingleton : ISingleton
{
    private static readonly Lazy<ConcreteSingleton> _instance = new Lazy<ConcreteSingleton>(() => new ConcreteSingleton());

    private ConcreteSingleton() { }

    public static ConcreteSingleton Instance
    {
        get
        {
            return _instance.Value;
        }
    }
}
  1. 改变单身人士课程 GetInstance(...) 方法

    在这种方法(我的首选方法)中,您不会每次都调用kernel.Inject(instance),而只是第一次初始化单例。将以下方法添加到ConcreteSingleton类:

    public static ConcreteSingleton GetInstance(IKernel kernelForInjection)
    {
        if (_instance.IsValueCreated == false)
        {
            kernelForInjection.Inject(_instance.Value);
        }
    
        return _instance.Value;
    }
    

    并使用此绑定:

    kernel.Bind<ISingleton>().ToMethod(c => ConcreteSingleton.GetInstance(c.Kernel));
    

    将实现没有公共构造函数但是能够有效注入外观的所需行为。

  2. 每次请求 ISingleton 实例时执行注入

    如果由于任何原因您不允许修改您的ConcreteSingleton:此方法将单例创建包装在提供程序中,以便仅在第一次创建实例时有效地注入实例。重要的是要注意提供者本身必须注册为单身人士。

    internal class ConcreteSingletonProvider : Provider<ISingleton>
    {
        public IKernel Kernel { get; set; }
    
        //Just a wrapper
        private readonly Lazy<ISingleton> _lazy = new Lazy<ISingleton>(() => ConcreteSingleton.Instance);
    
        public ConcreteSingletonProvider(IKernel kernel)
        {
            Kernel = kernel;
        }
    
        protected override ISingleton CreateInstance(IContext context)
        {
            if (_lazy.IsValueCreated == false)
            {
                Kernel.Inject(ConcreteSingleton.Instance);
            }
            return _lazy.Value;
        }
    }
    

    你的绑定应该是这样的:

    kernel.Bind<ISingleton>().ToProvider<ConcreteSingletonProvider>();
    kernel.Bind<ConcreteSingletonProvider>().ToSelf().InSingletonScope();
    

    gist为上述方法提供了完整的工作样本。

  3. 希望有所帮助!