2014-01-31 15 views
0

我在我的课程中只有一个副本。我不想使用Singleton模式,原因有很多(*见下文)。我知道我只会有一个类的副本,因为我将是唯一一个调用它的构造函数。这是一个很好的方法来检查是否只有一个类的实例存在,而不诉诸使用Singleton模式?

在我的类的构造函数中,我想检查该类的只有一个副本是否存在,并在存在多个类时抛出异常。下面的代码是否适合用于这种情况?

public class MySingletonAlternative : IDisposable 
{ 
    private static int _count = 0; 

    public MySingletonAlternative() 
    { 
     int newValue = System.Threading.Interlocked.Increment(ref _count); 
     if (newValue > 1) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    public void Dispose() 
    { 
     int newValue = System.Threading.Interlocked.Decrement(ref _count); 
     if (newValue < 0) 
     { 
      throw new ObjectDisposedException("MySingletonAlternative"); 
     } 
    } 
} 

*我为什么不想使用单例:

  1. 我希望能够创建该类时控制。在传统的C#单例模式中,构造发生非确定性。

  2. 我想避免全局变量。

  3. 当我调试我的代码并在Singleton的私有构造函数中引发异常时,Visual Studio会突出显示该异常,但它会突出显示错误的代码行,通常位于不同的文件中。

  4. 我不想懒惰地创建这个对象(使用Lazy <T>)。这个类的一个实例将存在于我的应用程序的生命中。我通过懒惰地构建它而获益匪浅。

+2

如果你有一个静态构造函数,正常单的建设是完全确定的。而你仍然有一个全局变量:计数器。一点也不清楚*为什么*要阻止创建多个实例。这有一些单身模式的缺点(例如缺乏可测试性),没有一些可疑的好处。 –

+0

根据http://msdn.microsoft.com/en-us/library/k9x6w0hc.aspx用户无法控制何时在程序中执行静态构造函数。另外,我不会将全局计数器考虑到我宣布它是私密的。 – user2023861

+0

这只是不真实的。对于没有存在静态构造函数的类型,它的类型初始值设定项有些* true,但是当存在静态构造函数时,C#规范非常明确:“执行静态构造函数是由以下事件中的第一个触发的:应用程序域: - \t创建类类型的实例 - 引用任何类类型的静态成员。“ –

回答

0

使用IoC容器,如UnityContainer。它会消除你提到的所有观点,你为什么不想使用单例(用全局变量或static)。您将能够完全控制您的生命周期实例的创建,并将其注入到所有需要使用此类的类中。

0

你可以使用依赖注入,然后让di容器管理你想创建的类的生命周期吗?一个例子是使用Unity和ContainerControlledLifetimeManager

http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx#sec34

+0

我认为依赖注入解决方案比我需要的更强大。我也不确定这会解决我的问题。我的项目很小,我不会经常更换组件或依赖项。我的问题最终是我的应用程序的生命中需要一个类的实例。这门课掌握一些数据并进行网络通话。我不想要重复的数据或不必要的网络呼叫;因此恰好是该类的一个实例。 – user2023861

+1

DI不大或难以添加到您的项目中。从你所说的话,它将解决你所列出的所有问题,而不仅仅是基于配置交换事情 - 但是使你以更可测试的方式编写代码,同时消除单身类固有的邪恶,因为它是可能的让您的应用程序的这方面为您管理。事实上,如果你不习惯DI,那么在一个小项目中开始使用DI是最容易掌握的方法。无论如何,祝你好运! – Jay

+0

这很有趣,我打算使用MySingletonAlternative的方式类似于我已阅读的有关依赖注入示例的内容。直到你提到它,我才知道它被称为。我在网上阅读过的例子看起来对我来说太强大了,但是我想用类来处理需要我一生的对象的例子是他们有一个setter,我将使用它来设置这个依赖关系, (构建生命周期对象需要一点点时间)。谢谢。 – user2023861

相关问题