Castle Project — варианты обновления синглтона Castle Windsor (истечение срока действия? уведомление?)

Я использую Castle Windsor 2.0 для внедрения зависимостей в моем проекте ASP.NET MVC 2.

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

<component id="Configuration" service="MyInterface, 
    MyAssembly" type="MyClass, MyAssembly2" lifestyle="Singleton" />

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

Возможные решения:

  1. Уменьшить время жизни пула приложений
  2. Попросите администраторов сайта повторно использовать пул приложений, если они хотят немедленного изменения.
  3. Переключиться на другой контейнер внедрения зависимостей
  4. Используйте один веб-сайт для всего
  5. Измените синглтон на PerWebRequest
  6. Создайте механизм, который позволяет интерфейсу администратора уведомлять приложение и обновлять синглтон.
  7. Заставьте синглтон истечь через установленное время, что приведет к обновлению

Я думаю, что вариант 7 (истечение срока действия синглтона) был бы идеальным, но после просмотра документации Castle может показаться, что функция истечения срока действия еще недоступна. индивидуальный образ жизни кажется возможным решением, но я не посмотреть, как я могу это реализовать.

Есть ли у кого-нибудь предложения о том, как реализовать варианты 6 или 7? Может быть, есть другое решение?


person Mayo    schedule 19.11.2010    source источник
comment
одноэлементное истечение — это оксюморон.   -  person Mauricio Scheffer    schedule 20.11.2010
comment
@Mauricio: Вы правы - я, вероятно, ищу что-то среднее между PerWebRequest и Singleton.   -  person Mayo    schedule 23.11.2010


Ответы (5)


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

person Ryan    schedule 19.11.2010
comment
Я не был уведомлен о вашем ответе (отсюда и поздний ответ), но забавно то, что я решил пойти по этому пути. Единственным ляпом было то, как я заставил синглтон проверять таймер — я связал проверку с геттером для общего свойства. Любые предложения по элегантному методу проверки таймера? - person Mayo; 23.11.2010
comment
Я всегда использую реактивные расширения: Observable.Interval(TimeSpan.FromHours(1)).Subscribe(i => Refresh()); - person Ryan; 20.01.2012

Можете ли вы создать зависимость от файла — например, web.config, но что-то еще — которая говорит синглтону перезагружать себя при изменении файла?

Я делаю что-то подобное с AutoFac для DI, но в моем случае я работаю с репозиториями в памяти для некоторых небольших коллекций часто используемых объектов, которые редко меняются. Когда они ДЕЙСТВИТЕЛЬНО меняются через веб-сайт maintennace, я касаюсь файла, который заставляет извлекать запись из кэша, срок действия которой истекает для всех кэшированных элементов, вызывая перезагрузку.

Не уверен, что это означает в Castle, поскольку мое решение также не связано с Autofac. Но, может быть, вместо синглтона в замке ваш объект конфигурации мог бы жить в кеше asp.net и так же истечь? Castle возвращает объект, который загружает данные в синглтон и при необходимости кэширует их (с файловой зависимостью).

person n8wrl    schedule 19.11.2010

Подобно @Mark 909, но вместо FileSystemWatcher (которому нужен файл) я бы использовал System.Threading.Mutex.

Веб-проект (с Синглтоном)

Я бы расширил Singleton с помощью Mutex (см. этот вопрос, чтобы правильно реализовать мьютекс). При инициализации синглтона я бы создал новый поток (используя ThreadPool или Task API), который блокирует доступ к WaitOne() вызов метода. Когда мьютекс получает сигнал, поток продолжит работу, и вы сможете перезагрузить конфигурацию. Не забудьте освободить мьютекс, вызвав ReleaseMutex().

Административный сайт

Добавьте ссылку Mutex на это приложение и всякий раз, когда вносятся изменения, которые должны привести к перезагрузке данных конфигурации, освобождайте Mutex с помощью ReleaseMutex(). Это приведет к тому, что веб-проект (т. е. синглтон) получит сигнал и выполнит перезагрузку. Не забудьте получить Mutex, используя WaitOne(). Поскольку это функция блокировки и это веб-сайт, вы можете рассмотреть WaitOne(TimeSpan). Используя небольшой TimeSpan, вы можете информировать пользователей административного сайта о том, что веб-проект все еще занят загрузкой конфигурации.

person M. Mimpen    schedule 28.11.2013

Я реализовал нечто подобное, используя Singleton в замке. Мой синглтон использует FileSystemWatcher для отслеживания событий изменения, а затем перезагружает данные в объект словаря в синглтоне при изменении файла. Этот файл содержит довольно статические справочные данные

Конечно, вам нужно будет решать проблемы параллелизма при перезагрузке данных в Singleton.

person Mark 909    schedule 25.11.2010

Я хотел поделиться тем, что у Ninject есть метод повторной привязки, который очень хорошо сработал для этого сценария. Переход с Castle на Ninject прошел относительно безболезненно.

void MvcApplication_BeginRequest(object sender, EventArgs e)
{
  if (/* criteria to refresh singleton */)
    this.Kernel.Rebind<IMySingleton>().To<MySingleton>().InSingletonScope();
}
person Mayo    schedule 30.12.2010