【问题标题】:Is using the singleton pattern a good idea when accessing libraries using MVC?使用 MVC 访问库时使用单例模式是个好主意吗?
【发布时间】:2015-06-03 15:32:32
【问题描述】:

我有一个网络应用程序,你已经知道这个应用程序会有很多请求,每个请求都将在不同的线程上运行,这意味着如果我使用单例访问我的 DAL 库,这不会有问题。

但是我不确定这是否是最好的方法,因为我读到一个请求有时我使用不同的线程,而且我还读到锁定线程有时会导致使用单个实例时性能下降。

为了让你更了解我,这就是我打算做的:

DAL

这是一个好方法吗?

这是我打算使用的单例:

     public static Products Instance
        {
            get
            {
                return Nested.instance;
            }
        }

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

       internal static readonly Products instance = new Products();

注意:我的 Dal 将使用 ADO.NET 访问数据库(我有理由使用 ado),而 BAL 只会使用此方法进行选择或 CRUD 操作。

我的 Ado.NET 代码:

public static readonly string ConnectionString = @"Server=localhost;Database=test;Uid=root;Pwd=test;";

    public bool IsProduct(string name)
    {
        var conn = new SqlConnection(ConnectionString);
        bool result;
        try 
        {
            conn.Open();
            var command = new SqlCommand();
            SqlParameter[] parameters = new SqlParameter[1];
            parameters[0] = new SqlParameter("@Product", name);
            command.Connection = conn;
            command.CommandText = "SPC_GET_PRODUCT";
            command.CommandType = System.Data.CommandType.StoredProcedure;
            result = Convert.ToBoolean(command.ExecuteScalar());
        }
        finally 
        {
            conn.Close();
            conn.Dispose();
        }
        return result;
    }

谢谢。

【问题讨论】:

  • 我们不知道。我们看不到您的 DAL 是如何实现的。是实体框架吗?它在自己的服务中吗?您的单身人士如何“访问” DAL?
  • 我更新了问题。
  • 这没有多大帮助,也没有回答我提出的任何问题。
  • 是实体框架吗?不,它是 ADO.NET。您的单身人士如何“访问”DAL? Products.Instance.GetProducts();
  • “GetProducts()”是做什么的?我们必须看看它是否是线程安全的代码。

标签: c# asp.net-mvc design-patterns singleton 3-tier


【解决方案1】:

总的来说,这可能不是一个好主意,原因如下:

  • 单例真的很难与多线程一起用于任何复杂的事情。您将调用的大多数库(如实体框架)不太可能是线程安全的,因此您需要进行大量锁定以保护资源。

  • 您几乎肯定会遭受性能方面的等待锁,而不是仅仅创建服务层的新实例。如果每个人都在等待一个单个数据库上下文,那么拥有一个完全异步的平台是没有意义的。

  • 它们很难进行单元测试

  • 语义不正确。单例的意思是只有 一个 类的实例。在某个时间运行您的业务逻辑的一个实例是没有意义的。

Singleton 在简单的事情上占有一席之地,比如访问配置数据,或者当创建一个实例时真的很昂贵。但在几乎所有其他情况下,有更好的方法来做到这一点。

other answers 解释了 Singleton 的所有问题。

【讨论】:

  • 我的 DAL 将与 ADO.net 合作
  • ADO.net 不是线程安全的。当单个请求使用数据库时,您需要锁定访问权限。 stackoverflow.com/questions/7316304/…
  • 我知道,但是看看我贴的代码,它没有使用锁,而且是线程安全的。
  • 这只是创建单例的代码。您仍然需要添加代码,这就是它停止线程安全的时候。当您有 2 个请求执行 Products.Instance.Database 或其他任何操作时,您将遇到错误。
  • 我不明白你为什么说它会遇到错误,如果它是线程安全的。
猜你喜欢
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 2011-11-03
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多