Перехват DateTime.Now в приложении .net - PullRequest
0 голосов
/ 25 мая 2018

У нас есть приложение, которое использует текущую дату (используя Datetime.Now) для вычисления определенных значений.

Нам необходимо иметь возможность выполнять эти вычисления на сервере также на основе другой даты.К сожалению, два очевидных варианта не являются жизнеспособными -

a), хотя у нас есть код для приложения, из-за политики и того факта, что другие среды также используют службу, не сможет ее изменить и внедритьконкретная дата и

b) из-за других приложений и процессов, запущенных на сервере, мы не можем изменить системную дату.

Мне было интересно:

было бы возможноперехватить вызовы, сделанные к платформе (Datetime.Now в этом случае) и вернуть определенное значение?Это может быть из того же приложения или нет.К сожалению, я не уверен, что вы действительно можете перехватывать эти вызовы таким образом, и даже тогда сможете идентифицировать процесс вызова.Я понимаю, что вы могли бы потенциально сделать это с некоторыми средами тестирования, но они потребуют от вас изменения вашей кодовой базы в любом случае.

спасибо

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Если у вас абсолютно нет другого способа, кроме исправления DateTime.Now во время выполнения - вы можете сделать это с помощью библиотеки Harmony .Я, очевидно, не буду рекомендовать делать такие вещи, но вы можете решить сами.

Сначала загрузите двоичный файл здесь (пока нет пакета nuget).Ссылка на него и затем:

class Program {
    static void Main(string[] args) {
        var now = DateTime.Now; // normal now
        var harmony = HarmonyInstance.Create("test");
        // patch
        harmony.PatchAll(Assembly.GetExecutingAssembly());
        // now + 100 years
        var newNow = DateTime.Now;
    }

    // we are rewriting method get_Now, which is a getter of property Now
    // of type DateTime
    [HarmonyPatch(typeof(DateTime), "get_Now")]
    class Patch {
        // this method runs after original one
        // __result stores value produced by original
        static DateTime Postfix(DateTime __result) {
            // add 100 years to it
            return __result.AddYears(100);
        }
    }
}

Это изменит DateTime.Now свойство getter во время выполнения, чтобы оно вернуло свое первоначальное значение + 100 лет.Очевидно, вы можете изменить это, чтобы возвращать любое нужное вам значение.

Этот патч не влияет на другие процессы, DateTime.Now будет работать как обычно для них.

0 голосов
/ 06 июня 2018

Действительно думал, что это будет проще сделать в .net, но в итоге я решил внести изменения в код.Хотя это изменение не является идеальным, оно не должно вызывать каких-либо проблем, о которых я мог подумать.

Высокий уровень - добавлена ​​функция datetimeprovider в приложение с функцией, принимающей строку и возвращающей datetime, которая вызывается вместо datetime.now.

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

Если совпадение не найдено, оно просто вернет datetime.now

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

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

0 голосов
/ 25 мая 2018

Гугл привел меня к программному обеспечению RunAsDate от NirSoft .Я не могу одобрить это программное обеспечение, но вижу, что оно утверждает, что делает именно то, что вы просите.

Пожалуйста, дайте нам знать, если это работает для приложений .NET!

...