【问题标题】:getting db connection through singleton class通过单例类获取数据库连接
【发布时间】:2010-10-23 06:54:18
【问题描述】:

我创建了一个单例类,这个类返回一个数据库连接。所以我的问题是这种连接也满足单身标准?
如果没有,那我怎么才能让它成为单身。
这是代码。

public sealed class SingletonDB
{
    static readonly SingletonDB instance = new SingletonDB();
    static SqlConnection con =new SqlConnection(ConfigurationManager.ConnectionStrings["mydb"].ConnectionString);

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static SingletonDB()
    {
    }

    SingletonDB()
    {
    }

    public static SingletonDB Instance
    {
        get
        {
            return instance;
        }
    }

    public static SqlConnection GetDBConnection()
    {
        return con;
    }
}

【问题讨论】:

  • 代码更新,现在评论新代码
  • 你有没有想过将 SQLConnection 依赖注入你的单例类?

标签: c# design-patterns singleton


【解决方案1】:

连接本身不满足单例标准,因为您可以创建数据库连接对象的多个实例。根据定义,单例只能实例化一次。

可以SqlConnection 变成单例的一部分,方法是将您的示例更改为:

public sealed class SingletonDB
{
    private static readonly SingletonDB instance = new SingletonDB();
    private readonly SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["mydb"].ConnectionString);

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static SingletonDB()
    {
    }

    private SingletonDB()
    {
    }

    public static SingletonDB Instance
    {
        get
        {
            return instance;
        }
    }

    public SqlConnection GetDBConnection()
    {
        return con;
    }
}

这样SingletonDB 类使用的SqlConnection 将只有一个SqlConnection,因此遵循单例模式。

【讨论】:

    【解决方案2】:

    在 .NET C# 中,你可以像这样写你的单例

        public class Singleton{
    public static readonly Singleton Instance= new Singleton();
    private Singleton(){}
    

    或者对于多线程环境:

    using System;
    
    public sealed class Singleton
    {
       private static volatile Singleton instance;
       private static object syncRoot = new Object();
    
       private Singleton() {}
    
       public static Singleton Instance
       {
          get 
          {
             if (instance == null) 
             {
                lock (syncRoot) 
                {
                   if (instance == null) 
                      instance = new Singleton();
                }
             }
    
             return instance;
          }
       }
    }
    

    【讨论】:

    【解决方案3】:

    单例意味着你创建的类只能被实例化一次。因此,如果您希望这种情况发生,请做两件事:

    1. 将构造函数设为私有。(这是为了防止其他类访问它。)
    2. 将类实例化为:

      get
      {
       if(instance == null) //important coz, the class will be instantiated only on the first call
       {
         instance = new singletonDb;
       }
       return instance;
      }
      

    【讨论】:

      【解决方案4】:

      你的 Singleton 仍然关闭。

      就单例模式而言,请在此处查看 Jon Skeet 的非常好的详细描述:http://www.yoda.arachsys.com/csharp/singleton.html

      对 SqlConnection 对象使用 Singleton 是一个非常非常糟糕的主意。没有理由这样做。

      如果您试图避免“new SqlConnection()”或“connection.Open()”的性能损失,请注意,由于连接池在幕后进行,因此确实没有性能损失。连接池处理 昂贵 连接的打开/关闭。不是 SqlConnection 对象。

      您将无法同时使用该连接打开多个 SqlDataReaders/Commands,并且如果您尝试与多个线程共享同一个连接对象,则会遇到线程阻塞问题。

      单例模式是最被过度使用和滥用的模式,单例模式有许多您可能不知道的副作用。很好的说说单身的危险http://www.youtube.com/watch?v=-FRm3VPhseI

      【讨论】:

      • 我这辈子都被骗了,不要在每次通话时都建立连接,因为“这会影响应用程序的性能”。
      • 在单例模式中指向updated Jon Skeet's article 的链接会派上用场。
      • 命令 =MySqlCommand() 怎么样?好不好,什么时候通过Singleton使用?
      • @Corio 我已提议对答案进行编辑,以将链接更改为您引用的链接。
      【解决方案5】:

      我想,如果没有看到一些代码,我无法回答这个问题。如果您说您的应用程序中只有一个数据库连接实例,那么如果您可以保证您的应用程序将仅在一个线程上运行(或至少所有使用数据库连接的操作都可以),那么这可能会起作用,因为您可以't(据我所知)在同一连接上并行运行多个操作。

      另外,如果这意味着您的应用程序将在两次使用之间保持连接打开,我建议您不要这样做。数据库连接是数据库服务器上的有限资源,因此您应该仅在需要时将其保持打开状态,然后再将其关闭。

      【讨论】:

        【解决方案6】:

        如果没有其他方法可以连接到数据库,并且无法覆盖此属性,我会说是。如果这就是你正在做的事情,那么你可能把这个单例的事情走得太远了。如果数据库暂时关闭并且您的应用程序失去连接怎么办?然后您必须重新启动您的应用才能再次使用数据库。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-14
          • 2012-06-05
          • 1970-01-01
          相关资源
          最近更新 更多