If absent, FetchAndCache invokes fetchFunction(). If the result is non-null, it creates a new SecureSettingCacheItem { Key = key, Value = val, FetchTime = DateTime.Now }, adds it via TryAdd, and returns val. If the fetch result is null, nothing is cached and default(T) is returned — a null/missing first fetch is not cached, so the next call will invoke the fetch delegate again.
If present, GetFromCache compares item.FetchTime < lastRefreshed (the caller's current LastRefreshed, which is updated by Refresh check and cache reload whenever a global reload happens) — this is a point-in-time comparison against the client's refresh timestamp, not an elapsed-seconds TTL check (BR-EC-23). If the cached item predates the last refresh, fetchFunction() is invoked again and item.Value/item.FetchTime are overwritten in place (even with a null result from a re-fetch — an existing cached value can be replaced by null on a stale re-fetch, unlike the initial-fetch case). The (possibly just-updated) item.Value is then converted via Convert.ChangeType(item.Value, typeof(T)) and returned (or default(T) if item.Value is null).
ClearCache() clears the entire dictionary. It is a public method on the class, but no caller in this repository invokes it.
flowchart TD
A["Get key, lastRefreshed, fetchFunction"] --> B{Key present in cache?}
B -- No --> C[Invoke fetchFunction]
C -->|non-null result| D["Cache SecureSettingCacheItem<br>with FetchTime = now"]
C -->|null result| E["Return default(T); nothing cached"]
D --> F[Return value]
B -- Yes --> G{"item.FetchTime < lastRefreshed?"}
G -- No --> K{"item.Value == null?"}
G -- Yes --> I[Invoke fetchFunction again]
I --> J["Overwrite item.Value/FetchTime<br>(even if result is null)"]
J --> K
K -- Yes --> L["Return default(T)"]
K -- No --> H["Return Convert.ChangeType(item.Value, T)"]