A time tracking application built with .NET and Windows Forms.
PricisApp now uses appsettings.json for configuration. This allows for easier customization without recompiling the application.
The configuration is structured as follows:
{
"Database": {
"FileName": "TimeTracking.db",
"ConnectionString": {
"Mode": "ReadWriteCreate",
"Cache": "Shared",
"Pooling": true
}
},
"Logging": {
"MinimumLevel": "Debug",
"FilePath": "Logs/pricisapp-{Date}.log",
"RetainedFileCount": 7,
"FileSizeLimitBytes": 10000000
},
"UI": {
"DefaultTheme": "System Default",
"AvailableThemes": [
"System Default",
"Light",
"Dark",
"Blue",
"Green",
"High Contrast"
],
"DefaultFont": {
"Name": "Segoe UI",
"Size": 9.0
}
}
}Configuration can be accessed in two ways:
-
Using IConfigurationService
The recommended way to access configuration is through the
IConfigurationServiceinterface:public class MyClass { private readonly IConfigurationService _configService; public MyClass(IConfigurationService configService) { _configService = configService; // Access configuration values string dbFileName = _configService.GetDatabaseFileName(); string defaultTheme = _configService.GetDefaultTheme(); string[] themes = _configService.GetAvailableThemes(); // Get any value by key int retryCount = _configService.GetValue<int>("SomeSection:RetryCount", 3); } }
-
Using IConfiguration and AppSettings
For more direct access, you can use the
IConfigurationandAppSettingsclasses:public class MyClass { private readonly IConfiguration _configuration; private readonly AppSettings _appSettings; public MyClass(IConfiguration configuration, AppSettings appSettings) { _configuration = configuration; _appSettings = appSettings; // Access configuration values string dbFileName = _appSettings.Database.FileName; string defaultTheme = _appSettings.UI.DefaultTheme; // Get any value by key int retryCount = _configuration.GetValue<int>("SomeSection:RetryCount", 3); } }
To customize the application's configuration:
- Edit the
appsettings.jsonfile in the application directory - Restart the application for changes to take effect
User-specific settings (like the selected theme) are still stored in the user's local application data folder for backward compatibility, but the application now uses the configuration service as the primary source of configuration values.
- Added
Core/TimerController.cs: an async, event-driven, reusable timer class. - Used by
SessionServicefor all timer logic.
- Added
Microsoft.Extensions.Caching.Memory. TaskServicenow caches task and tag lookups for performance.- Cache is invalidated on create, update, or delete.
BaseRepositoryalready had robust retry logic for transient DB errors.- Logic reviewed and left as is.
TaskServiceTestsupdated for new constructor and cache behavior.- Add more tests for services as needed.
- Dapper added to project.
- Example:
TaskRepository.InsertTaskAsyncnow uses Dapper. - To migrate more methods, replace raw SQL with Dapper's
QueryAsync,ExecuteAsync, etc.
- Replace
cmd.CommandTextand parameter setup with Dapper's parameterized methods. - Use
connection.QueryAsync<T>(sql, new { param1, param2 })for queries. - Use
connection.ExecuteAsync(sql, new { ... })for non-queries.
- Inject
IMemoryCacheinto services. - Use
cache.Set(key, value, expiry)andcache.TryGetValue(key, out value). - Invalidate cache on data changes.
- Create:
var timer = new TimerController(TimeSpan.FromMilliseconds(100)); - Events:
timer.Tick += ...,timer.Started += ..., etc. - Methods:
Start(),Stop(),Pause(),Resume(),ResetTimer()
For more details, see code comments and service constructors.