ASP.NET — машина времени в помощь разработчику

от автора

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

Что нужно

Для этого нам просто нужно изолировать зависимости системы от времени. Для .NET кода это значит заменить вызовы DateTime.Now (Today, UtcNow, и т.д.). Я предлагаю простой вариант реализации такого TimeService для .NET.

Запускаем

Итак, у вас есть сайт. Чтобы добавить «машину времени»:

1. Добавляем класс TimeService. Он будет заменять нам DateTime, когда нам будет надо узнать текущее время. Пример реализации я положил в gist.

2. Находим все места использования DateTime.Now (Today, UtcNow) в нашем коде (утилиты для рефакторинга нам здесь будут очень полезны). И заменяем их на TimeService.Now и т.п.

3. Опционально делаем несложную страницу с календариком, которая будет вызывать сеттер TimeService.Now или UtcNow, или делать TimeService.Reset(), когда нужно вернуть время к актуальному. Т.к. наш TimeService хранит сдвиг относительно времени в реестре — вы вполне можете в первое время обойтись regedt32.exe для изменения времени.

Всё. Теперь ваш сайт живёт в контексте времени из вашего TimeService.

Синхронизация между процессами

Хранение значения сдвига времени в реестре позволяет использовать одно и тоже время в нескольких процессах (для web-garden — конфигураций). Или например, если в дополнение к вашему сайту, всем биллингом управляет отдельный системный сервис — время везде будет одинаковое.

В любом случае, чтобы всё пошло как по маслу, надо добавить доступ к нужной ветке реестра всем его пользователям (Network Service, пользователь IIS AppPool и т.д.). По-умолчанию машина времени хранит своё значение в HKEY_USERS\.DEFAULT\Software\TimeService. Это место позволяет давать доступ любому пользователю и не сталкиваться с UAC (в отличие от HKLM).

Базы данных, файловая система

Нужно понимать, что наша машина времени способна влиять только на ограниченный набор подконтрольного нам кода. И учитывать это при разработке. Например, если вы где-то полагаетесь на временные значения с файловой системы, или вызовы GETDATE()/GETUTCDATE() к СУБД, то тут вам необходимо продумать эти вопросы отдельно.

Надеюсь, эта статья будет полезна, как идея и как пример.
Усовершенствования и новые идеи — приветствуются.

ссылка на оригинал статьи http://habrahabr.ru/post/160173/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *