ITLab.Template.DevPack.Abstractions
Defines foundational contracts consumed by infrastructure and application layers.
Componentes
| Tipo | Nome | Responsabilidade |
|---|---|---|
| Interface | IAppOptions | Marks bindable options and declares the configuration section path |
| Interface | ICacheService | Cache contract for get/create, set, try-get, remove and diagnostics |
| Interface | IDateTimeProvider | Time normalization contract for UTC/system/user-local values |
| Sealed Class | UtcDateTimeProvider | Default IDateTimeProvider — every value resolves to UTC; singleton |
| Sealed Class | LocalDateTimeProvider | IDateTimeProvider that converts to ICurrentUser.LocalTimeZone (IANA), fallback UTC; scoped |
| Static Class | DateTimeProviderServiceCollectionExtensions | DI helpers AddDevPackUtcDateTimeProvider() / AddDevPackLocalDateTimeProvider() |
| Interface | IServiceProviderAccessor | Provides controlled access to the active service provider |
Como usar
// App options contract used by strongly typed configuration.
public sealed class MyFeatureOptions : IAppOptions
{
public static string ConfigSectionPath => "MyFeature";
public bool Enabled { get; init; }
}
// Cache usage with safe fallback factory.
var customer = await cacheService.GetOrCreateAsync(
cacheKey: $"customer:{id}",
factory: () => repository.LoadCustomerAsync(id),
absoluteExpiration: TimeSpan.FromMinutes(10));
DateTimeProvider — escolha por host
| Host | Implementação | Lifetime | Por quê |
|---|---|---|---|
| Web API com user context | LocalDateTimeProvider | Scoped | UserLocal* resolve via ICurrentUser.LocalTimeZone |
| Worker / batch / console | UtcDateTimeProvider | Singleton | Sem user context — degrade para UTC, sem custo de scope |
| Fallback / testes | UtcDateTimeProvider | Singleton | Determinístico, sem dependências scoped |
Registro
// Pré-requisito para ambos:
services.AddSingleton(TimeProvider.System);
// Web API:
services.AddDevPackLocalDateTimeProvider(); // Scoped
// requer ICurrentUser registrado (do DevPack Identity).
// Worker:
services.AddDevPackUtcDateTimeProvider(); // Singleton
Comportamento de timezone
LocalDateTimeProvider resolve ICurrentUser.LocalTimeZone (IANA) via
TimeZoneInfo.TryFindSystemTimeZoneById. Em .NET 8+ no Windows, identificadores
IANA são aceitos diretamente — o runtime aplica mapeamento IANA↔Windows
internamente. Não é necessário tratamento por plataforma.
Fallback silencioso para UTC quando LocalTimeZone é null, vazio ou
desconhecido ao runtime — LocalDateTimeProvider nunca lança exceção.
// Cenário: usuário em São Paulo (IANA "America/Sao_Paulo"), UTC = 2026-05-01 15:00.
// provider.UserLocalTimeOffset = 2026-05-01 12:00 -03:00
// provider.UserTimeZone = TimeZoneInfo for America/Sao_Paulo
// provider.UserLocalTimeOffsetSpan = -03:00:00
// Cenário: usuário sem LocalTimeZone definido (LocalTimeZone == null).
// provider.UserLocalTimeOffset = 2026-05-01 15:00 +00:00 (UTC)
// provider.UserTimeZone = TimeZoneInfo.Utc
// provider.UserLocalTimeOffsetSpan = TimeSpan.Zero
O que não fazer
- Do not use
IServiceProviderAccessoras a generic service locator in domain code. - Do not store mutable runtime state in
IAppOptionsimplementations. - Do not rely on cache as the source of truth for business consistency.
- Do not register
LocalDateTimeProvideras Singleton — depends on scopedICurrentUser. - Do not throw or log error when timezone is invalid —
LocalDateTimeProviderfalls back to UTC by design.
Extensão pelo produto
- Products can implement custom
IDateTimeProvider(e.g. multi-tenant timezone strategies) and replace the registration. - Products can replace
ICacheServicewith distributed cache implementations while keeping contract behavior.