2

嗨,我有兴趣实现一个返回单例对象的方法。我根据 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;
    }
}
4

3 回答 3

6

随着双重检查的实施,是的 - 可以正常工作。它甚至不需要volatile,因为同步的双重检查将处理任何少量的“这是一个错误的null读取”。就个人而言,我更关心它似乎不尊重 API的事实——即,如果我询问一个实例是否指定了特定的 context-factory 和 logger,它实际上给了我一些使用不相关上下文的东西——工厂和记录器。坦率地说,还有 IoC/DI 容器,您可以简单地将其卸载到。

于 2013-08-28T09:57:32.997 回答
0

用于object.ReferenceEquals()检查两个对象是否是同一个实例。

例如:

    [TestMethod]
    public void TestGetFileShareAccessInstance()
    {
        var first = FileShareAccessFactory.GetFileShareAccessInstance(contextFactory, logger);
        var second = FileShareAccessFactory.GetFileShareAccessInstance(contextFactory, logger);

        Assert.IsTrue(object.ReferenceEquals(first, second));
    }
于 2013-08-28T09:54:23.970 回答
0

我现在注意到您的构造函数中有依赖项,如果这确实是单例,那么它们也必须是单例。如果不是,那么你想再次考虑这个作为一个单身人士。

你可能想看看 Unity 等依赖注入。通过这种方式,您可以注册此类ContainerControlledLifetimeManager以在上下文工厂、记录器和此对象上强制执行单例。它允许稍后的灵活性,您可能有更多的上下文工厂,因此需要更多FileShareAccessFactory的 s。

如果您将代码保留为仅强制执行一个实例,则必须进行的其他改进:

  1. 将构造函数设为私有。
  2. 密封类 - 或者可以构建一个下降类。
于 2013-08-28T09:56:08.400 回答