我有以下情况:
问题是,这个单例类是仅为所有这些虚拟目录实例创建了一次,还是为每个目录创建了一个单独的单例类。
代码看起来像这样:
[
Transaction(TransactionOption.Supported),
ClassInterface(ClassInterfaceType.AutoDispatch),
Guid("7DE45C4D-19BE-4AA4-A2DA-F4D86E6502A8")
]
public class SomeClass
{
private static readonly Singleton singleton = new Singleton();
答案 0 :(得分:7)
将为使用它的每个应用程序创建一个单例。每个应用程序彼此分开,因为它们各自存在于它们自己的application domain中。
要在不同的应用程序中拥有真正的单例类,您需要让它们与保存信息的公共应用程序进行通信(例如通过远程处理或WCF等)。
application pool控制该池中的内存和处理器应用程序可以访问的程度(以及程序运行的帐户)。他们仍然是彼此分开的。
答案 1 :(得分:1)
在IIs中,每个虚拟目录都有一个与之关联的应用程序。应用程序不与其他应用程序共享内存空间,因此每个虚拟目录都会有一个此类的新实例。
您可以创建所有这些应用程序将使用的共享应用程序池。但是,在这种情况下,内存将被共享,但每个内存将使用该内存获得一个唯一的进程,每个唯一的进程将加载该类。
答案 2 :(得分:1)
将来自不同位置的程序集(DLL)加载到.net CLR(即使是相同文件的相同副本到同一进程(*)中),CLR将其中的每一个视为单独的程序集...所以类型在这些程序集 - 虽然在语法上相同(甚至在命名空间术语中) - 仍然是不同的类型!
因此,即使它们位于相同的应用程序上下文(操作系统进程)中,单例也不会是调用者之间的单个公共实例(您将拥有同一类的三个单独的静态实例)。另外:应用程序上下文被定义为具有基本路径(在ASP.Net情况下,这是虚拟目录)...进一步证明Web应用程序都在不同的进程中运行(Kevin是对的)。
关于复制DLL只是一个普遍的观点(也许是关于你的问题的主题):全局程序集缓存(GAC)带来了不同的挑战......但CLR对“DLL地狱”的反应是对待每一个不同的文件(相同或不相同)作为单独的程序集...使用GAC - 我强烈建议不要将程序集复制到一台机器上的多个位置。没有别的:这样的文件复制是部署的噩梦。 GAC附带了各种强大的版本管理实用程序(检查:GAC绑定策略)。
希望能帮助您解决长期问题......
Aidanapword
(*)这可以使用反射来完成......不是一个好主意但它会发生。
答案 3 :(得分:1)
首先注意 - 当您在IIS 6和7下运行时,如果允许IIS为每个AppPool使用多个进程,则AppDomains可以位于单独的工作进程中。为了将其置于适当的历史环境中,AppDomain只是模拟IIS AppPool机制对任何二进制文件的作用。允许很多可伸缩性,在许多情况下,如果你有一些“单例”副本并不重要 - 这也可以提高性能。
如果你真的,真的,我的意思是真的:-)需要一个服务器级单例,有一种方法可以做到这一点,而无需支付远程处理的成本,但前提是你知道你的COM或WinNT API
WinNT路由将是最轻量级的资源,但你必须完成WinNT工作才能开始问你为什么还在C#而不是C ++ - 共享内存,事件或WinNT互斥等。COM路由将要求你强制退出proc调用(正确的注册表项),你可能想要使用AutoDual而不是AutoDispatch - 首先购买perf和第二个以确保.NET具有最小的处理dll为“它自己的”。 gola是为了让它看起来和任何其他的proc COM一样嘎嘎叫
要问自己的重要问题是 - 为什么我真的需要它?如果目的是缓存,则需要使用非常不同的策略,而不是快速事件处理(在这种情况下,MSMQ将很好地服务 - 它现在在WCF的保护伞下)。