C# 单例模式的正确使用
我有一个要求,即只创建一个C# 单例模式的正确使用,c#,.net,singleton,C#,.net,Singleton,我有一个要求,即只创建一个BillLines实例,这当然非常适合单例模式 看一下,我不太明白我在哪里创建了我的“新”对象(即有用的对象,而不是一些抽象的单例对象) 你觉得这对吗 public sealed class ContextSingleton { private static readonly Lazy<ContextSingleton> Lazy = new Lazy<ContextSingleton>(() => new Cont
BillLines
实例,这当然非常适合单例模式
看一下,我不太明白我在哪里创建了我的“新”对象(即有用的对象,而不是一些抽象的单例对象)
你觉得这对吗
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();
}
更新
我无法访问
BillLines
的内部,但我需要确保它只存在一个实例。我假设BillLines
应该是您的实例变量
应该是这样的:
var contextSingleton = ContextSingleton.Instance.Context;
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
类的公开,那么您应该使它只在您公开的单例的内部实现中公开,这样其他人就不能创建他们认为合适的新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的评论,我走上了依赖注入的道路。我选择了它,它完成了我预期的工作:
public class NinjectBindings : NinjectModule
{
public override void Load()
{
Bind<IBillLineEntities>.To<BillLines.BillLines>().InSingletonScope();
}
}
公共类NinjectBindings:NinjectModule
{
公共覆盖无效负载()
{
Bind.To().InSingletonScope();
}
}
你到底想成为什么样的单身汉?(你确定你必须使用这种模式吗?我倾向于避免,我自己…)如果你的广告牌第二次出现,世界会以某种方式结束吗?因为您只需要其中一个并不是单例的原因,就像只需要一个int并不意味着int应该是单例一样。如果你有一个单件产品,你将如何对你的产品进行单元测试?你搞错了。如果需要将BillLines
作为单例,则需要将其构造函数private
和实例设置为从该类返回。将ContextSingleton
设为私有是没有用的。任何人都可以调用new BillLines()
任意次数。@JonSkeet-我想BillLines
成为单身汉@nvoigt-是,多个实例在意外事务升级方面导致问题。BillLines
是命名空间还是类型?我担心新的BillLines.BillLines()
…-1顺便说一句,这不是一个单身汉。是什么阻止了客户端创建广告行
自身的实例?为什么这不是一个单例?他不应该将广告行
作为一个公共类公开给客户端,它应该是底层实现的内部类。@YuvalItzchakov这不是单例的意思。这意味着您只能创建一个实例。如果您的代码本身创建了新的BillLines()
这如何使其成为单例?@YuvalItzchakov它不会阻止创建其他实例。Siriam应用了相当严格的singleton定义,其中类有一个私有构造函数,不可能创建其他实例。我更喜欢将单例看作一个更广泛的概念,您只需要一个实例。这个更广泛的定义还包括一些变体,其中IoC容器只创建一个实例,而类本身不强制执行该限制。这不是线程安全的。OP的代码使用了Lazy
,它封装了单个实例的线程安全创建。使用它通常是最好的选择。