В проекте используется TimerService для генерации меток времени.
На TimerService подписаны DataGeneratorService, отвечающие за генерацию записей и отправку в БД через IDataStorage.
MainViewModel подписана на DataGeneratorService и получает уведомления о появлении новых записей по факту записи в БД. Передает изменение во вью (MainWindow). MainViewModel отвечает за отслеживание совпадения меток времени и выдачи соответствующего сообщения в лог (спорное решение, но пусть).
DbViewModel используется на вспомогательной форме для отображения записей БД. Записи перечитываются с заданной периодичностью (можно менять). Данные на форме читаются из VIEW в БД (FULL JOIN таблиц водителей и автомобилей). Решение через VIEW не очень удачно, т.к. EF пытается постоянно кешировать записи, прочитанные из БД, то при частом обновлении DbViewModel возникает ситуация когда строка читается и БД, а чуть позже за эту же метку времени прилетает запись в одну из таблиц и меняет VIEW, но EF конечно такое не отслеживает. Прикрутил костыль, времени нет сделать нормально (возможно на запрос FromSql).
Все объекты создаются через DI. Но за создание Window отвечает IWindowsCreator (реализованный в App). Сделал так чтобы оставить конструкторы окон internal и не дать их создавать через DI (создание осталось на уровни вью). Для логов используется Serilog. Правда оказалось что Serilog.Sinks.File не умеет поддерживать rollingInterval длительностью больше 1. Пришлось форкнуть проект и допилить (serilog/serilog-sinks-file#323).
Все настройки логов, таймаутов создания записей, строка подключения и имена сущностей для генерации задаются в конфиге json. БД – SQLite с поддержкой миграций. Создается и мигрирует сама при запуске приложения.