单例模式如何在Web上下文中工作?

时间:2012-07-06 12:37:27

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

因此,使用单例模式的对象只能有一个实例。这在网站上如何运作?

问题:

  1. 单身对象是否对网站的每个客户/访客都是唯一的?即单例对象是否获得一个PER客户端实例?
  2. Web应用程序中的对象只持续几秒钟,因此如果两个客户端同时访问网站,则两个客户端都将尝试创建单个对象。这是否意味着有人会看到一个例外,游客会看到这个例外情况?我试过谷歌搜索,但找不到直接的答案。我只想找一点澄清。

5 个答案:

答案 0 :(得分:8)

史蒂夫,我会尽力回答你的每一个问题:

1)对于Web开发,将对象作为Web请求的范围是很常见的(有时这也称为“每个请求上下文”或“每个http上下文”),但我们通常不会引用这些作为单身人士的确切原因。实际上,大多数IOC容器都具有开箱即用的“每个Web请求”范围以及“单例”。

2)有时候Web应用程序也会有真正的单例(所有请求都可以访问)。如上所述,这并不完全正确,因为它将限定在应用程序池中,并且当/如果重新启动应用程序池时将被吹走。但这是用于Web应用程序的单例。正如Jigar所提到的,有时候“横切关注”,例如伐木等......都是这样设置的。这些通常不会在每个Web请求中初始化,而是在global.asax中或通过依赖IOC容器为您执行此操作。您只需要确保在执行对​​象创建时使用其中一个标准锁定模式来防止两个线程/客户端/等等同时创建对象。这里有一个来自Microsoft的链接,但也有其他实现:http://msdn.microsoft.com/en-us/library/ff650316.aspx如果你使用一个流行的IOC容器,它将为你处理这个(Structuremap,Windsor,Autofac,Unity,Ninject ..和其他许多人。)

你需要向你的同事询问他们所指的方法,因为两者在某些情况下都是有效的并且非常普遍。

答案 1 :(得分:2)

这一切都取决于你的单例实现。在这里,我假设您创建单例作为在静态构造函数中初始化的静态字段。

理论上,根据其设置,IIS可以为您的应用程序创建多个进程,每个进程可以创建多个线程来处理请求。每个进程都有自己的单例,可以共享多个线程(以及多个请求)。但同时在一台服务器上可能存在多个“单例”实例(每个进程一个)(但是,如果我理解正确,IIS设置中可以禁止多个进程)。

如果使用静态构造函数,那么将以线程安全的方式在第一次访问类时创建单例。见Is the C# static constructor thread safe?

但是虽然单例创建是线程安全的,但你仍然必须以线程安全的方式实现单例类的内部。

单身人士会在您的申请流程存在且未重新启动时生效。应用程序的生命周期由IIS管理,因此可能需要很长时间或很短的时间。

答案 2 :(得分:1)

Singleton由IIS维护,因此单例只会持续IIS应用程序池。一旦这被回收或重置IIS,单身就会消失。您需要锁定单例才能进行多次访问。就像在任何其他客户端服务器应用程序中一样。

通常我会尝试避免它,因为它反对网站本质上是无状态客户端服务器应用程序的想法。为什么不使用Session来存储任何共享数据?

答案 3 :(得分:0)

对于记录器和共享资源,我们可以确保在Web应用程序中使用单例。并且正如Liam所说,只要您的应用程序池未被清除,它们就会保留。

为了更好地理解,请访问... http://www.oodesign.com/singleton-pattern.html

由于

答案 4 :(得分:-1)

public class SingletonContext<TContext>
    where TContext: DbContext,new()
{
    private static TContext _context;

    private SingletonContext()
    {

    }
    public static TContext GetInstance()
    {
        if (_context == null)
        {
            _context = new TContext();
        }
        return _context;
    }

}