Singleton实现检查
本文关键字:检查 实现 Singleton | 更新日期: 2023-09-27 18:29:29
嗨,我对实现一个返回单例对象的方法很感兴趣。我已经根据MSDN上的一个例子创建了一个实现,但我真的不确定我的实现是否正确。
代码运行得很好,但我不知道如何检查它是否是同一个对象实例。
这是我的代码:
public class FileShareAccessFactory : IFileShareAccessFactory
{
private volatile static IFileShareAccess m_fileShareAccess;
private static object m_SyncRoot = new object();
public IFileShareAccess GetFileShareAccessInstance(IContextFactory contextFactory, ILogger logger)
{
if (m_fileShareAccess == null)
{
lock (m_SyncRoot)
{
if (m_fileShareAccess == null)
{
m_fileShareAccess = new FileShareAccess(contextFactory, logger);
}
}
}
return m_fileShareAccess;
}
}
随着双重检查的实现,是的,这会正常工作。它甚至不需要volatile
,因为同步的双重检查将处理任何少量的"它是一个错误的null
读取"。就我个人而言,我更关心的是它似乎不尊重API这一事实-即,如果我问一个实例是否指定了一个特定的上下文工厂和记录器,它实际上给了我一些使用了无关的上下文工厂和日志的东西。坦率地说,也有IoC/DI容器,您可以简单地将其卸载到。
使用object.ReferenceEquals()
检查两个对象是否为同一实例。
例如:
[TestMethod]
public void TestGetFileShareAccessInstance()
{
var first = FileShareAccessFactory.GetFileShareAccessInstance(contextFactory, logger);
var second = FileShareAccessFactory.GetFileShareAccessInstance(contextFactory, logger);
Assert.IsTrue(object.ReferenceEquals(first, second));
}
我现在注意到你的构造函数中有依赖项,如果这真的是一个singleton,那么它们也必须是singleton。如果没有,那么您需要将其作为一个单例重新考虑。
您可能需要查看依赖项注入,例如Unity。通过这种方式,您可以向ContainerControlledLifetimeManager
注册此类,以便在上下文工厂、记录器和此对象上强制执行单例。它允许以后的灵活性,因为您可能有更多的上下文工厂,因此需要更多的FileShareAccessFactory
s。
如果您保留代码只执行一个实例,则必须进行其他改进:
- 将构造函数设为私有
- 密封类-或者可以构造一个派生类