Класс Singleton в DLL, используемый в нескольких виртуальных каталогах - PullRequest
1 голос
/ 24 марта 2010

У меня следующая ситуация:

  • несколько виртуальных каталогов в одном пуле приложений в IIS
  • копия одной и той же DLL во всех этих каталогах (с одинаковым номером версии)
  • одноэлементный класс в одном в этой DLL

Вопрос в том, является ли этот одноэлементный класс созданным только один раз для всех этих экземпляров Виртуального каталога, или для каждого из этих каталогов существует отдельный одноэлементный класс.

Код выглядит примерно так:

    [
Transaction(TransactionOption.Supported),
ClassInterface(ClassInterfaceType.AutoDispatch),
Guid("7DE45C4D-19BE-4AA4-A2DA-F4D86E6502A8")
]
public class SomeClass
{
    private static readonly Singleton singleton = new Singleton();

Ответы [ 4 ]

7 голосов
/ 24 марта 2010

Для каждого приложения, использующего его, будет создан синглтон. Каждое приложение отделено друг от друга, поскольку каждое из них существует в своем собственном домене приложения .

Чтобы иметь по-настоящему одноэлементный класс для разных приложений, вам нужно, чтобы они связывались с общим приложением, содержащим информацию (например, с помощью удаленного взаимодействия или WCF и т.

Пул приложений управляет объемом памяти и процессорных приложений в этом пуле (вместе с учетной записью, под которой запускаются программы). Они все еще отделены друг от друга.

1 голос
/ 19 августа 2010

Первое замечание - при запуске под IIS 6 и 7 домены приложений могут находиться в отдельных рабочих процессах, если вы разрешаете IIS использовать несколько процессов для одного AppPool. Чтобы поместить его в надлежащий исторический контекст, AppDomain просто эмулирует то, что механизм IIS AppPool будет делать с любым двоичным файлом. Обеспечивает большую масштабируемость, и во многих случаях это не имеет значения, если у вас есть несколько копий «синглтона», что также может улучшить производительность.

Если вы действительно, действительно, и я имею в виду действительно :-), вам нужен синглтон серверного уровня, есть способ сделать это, не оплачивая затраты на удаленное взаимодействие, но только если вы знаете свой COM или WinNT API .

Маршрут WinNT будет самым легким в плане ресурсов, но вам придется выполнить полную работу WinNT до того момента, когда вы начнете спрашивать, почему вы все еще находитесь в C #, а не в C ++ - общая память, события или мьютексы WinNT и т. Д.

COM-маршрут потребует от вас принудительного вызова proc (правильные ключи реестра), и вы можете использовать AutoDual вместо AutoDispatch - сначала купить perf, а затем убедиться, что .NET имеет минимальный шанс длл как "свой". Цель состоит в том, чтобы заставить его выглядеть и крякать, как и любой другой из proc COM

Важный вопрос, который нужно задать себе: зачем мне это на самом деле? Если целью является кэширование, необходимо использовать совсем другую тактику, а не быструю обработку событий (в этом случае MSMQ будет хорошо работать - теперь он находится под эгидой WCF).

1 голос
/ 24 марта 2010

Загрузка сборки (DLL) из разных мест в .net CLR (даже идентичную копию одного и того же файла в один и тот же процесс (*)), CLR обрабатывает каждую из них как отдельные сборки ... так что типы в эти сборки - хотя они синтаксически идентичны (даже в терминах пространства имен) - все еще разных типов!

Таким образом, даже если бы они находились в одном и том же контексте приложения (процесс ОС), синглтон не был бы одним общим экземпляром среди вызывающих (у вас было бы три отдельных статических экземпляра одного и того же класса). Также: контекст приложения определяется как наличие базового пути (в случае ASP.Net это виртуальный каталог) ... еще одно доказательство того, что все веб-приложения выполняются в отдельных процессах (Кевин прав).

Просто общее замечание (возможно, не по теме вашего вопроса) о копировании DLL, хотя: глобальный кэш сборок (GAC) сопряжен с различными проблемами ... но ответ CLR на "ад DLL" заключается в том, чтобы рассматривать все разные файл (идентичная копия или нет) как отдельная сборка ... используйте GAC - я настоятельно рекомендую не копировать сборки в несколько мест на одном компьютере. Если ничего другого: такое копирование файлов - кошмар развертывания. GAC поставляется со всевозможными мощными утилитами управления версиями для загрузки (см. Раздел Политики привязки GAC).

Надеемся помочь с вашим долгосрочным решением ...

Aidanapword

(*) это можно сделать с помощью Reflection ... не очень хорошая идея, но это случается.

1 голос
/ 24 марта 2010

В II каждый виртуальный каталог связан с одним приложением. Приложение не делит пространство памяти с другими приложениями, поэтому для каждого виртуального каталога будет создан новый экземпляр этого класса.

Вы можете создать общий пул приложений, который будут использовать все эти приложения. Однако в этом случае память будет разделена, но каждый получит уникальный процесс, использующий эту память, и каждый уникальный процесс загрузит класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...