正确使用单例模式

本文关键字:单例模式 | 更新日期: 2023-09-27 18:16:40

我有一个需求,只创建一个BillLines的实例,这当然是完美的单例模式。

看Jon的Skeet的帖子,我不太明白我在哪里创建了我的"新"对象(即有用的对象,而不是一些抽象的单例对象)。

你觉得这样对吗?

public sealed class ContextSingleton
{
    private static readonly Lazy<ContextSingleton> Lazy =
        new Lazy<ContextSingleton>(() => new ContextSingleton());
    public static ContextSingleton Instance { get { return Lazy.Value; } }
    private ContextSingleton()
    {
    }
    //Is this correct?  Where should I 'new' this?
    public readonly IBillLineEntities Context = new BillLines.BillLines();
}

被这样访问:

var contextSingleton = ContextSingleton.Instance.Context;

我不能访问BillLines的内部,但我需要确保它只存在一个实例。

正确使用单例模式

我假设BillLines应该是您的Instance变量。

应该是这样的:

public static class ContextSingleton
{
    private static readonly Lazy<BillLines> _instance =
        new Lazy<BillLines>(() => new BillLines());
    public static BillLines Instance { get { return _instance.Value; } }
    private ContextSingleton()
    {
    }
}

你可以这样使用:

ContextSingleton.Instance

编辑

这个答案针对的是创建一个关于特定类的单例。如果其他人可以访问您的BillLines类,并且可以创建他们自己的实例,那么您可能应该重新考虑您正在尝试做的事情。如果你控制BillLines类的暴露,你应该使它只暴露在你所暴露的单例的内部实现中,这样其他人就不能创建他们认为合适的new BillLines

像这样简单吗?

public class BillLines
{
    private BillLines()
    {
    }
    private static BillLines _billLines = null;
    public static BillLines Instance
    {
        get
        {
            if (_billLines == null)
                _billLines = new BillLines();
            return _billLines;
        }
    }
}

感谢@JonSkeet和@RobH的评论,我走了依赖注入的路线。我选择了Ninject,它完成了我预期的工作:

public class NinjectBindings : NinjectModule
{
    public override void Load()
    {
        Bind<IBillLineEntities>.To<BillLines.BillLines>().InSingletonScope();
    }
}