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

Singleton实现检查

随着双重检查的实现,是的,这会正常工作。它甚至不需要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。

如果您保留代码只执行一个实例,则必须进行其他改进:

  1. 将构造函数设为私有
  2. 密封类-或者可以构造一个派生类