
// ✅ Injectable, testable
public class OrderService(TimeProvider time)
{
public bool IsExpired(Order order) =>
time.GetUtcNow() > order.ExpiresAt;
}
// 🧪 In tests — using FakeTimeProvider (Microsoft.Extensions.TimeProvider.Testing)
var fakeTime = new FakeTimeProvider();
fakeTime.SetUtcNow(
new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero));
var service = new OrderService(fakeTime);
// ⚙️ In production (DI registration)
services.AddSingleton(TimeProvider.System);
🚫 Stop hardcoding time in C#
Inject `TimeProvider` for testable, controlled time.
`FakeTimeProvider` allows precise time manipulation in tests.
Register `TimeProvider.System` for production real-time.
with .NET 8's TimeProvider abstraction

// ❌ Before: one overload per type
static int Sum(IEnumerable<int> numbers)
=> numbers.Aggregate((a, b) => a + b);
static double Sum(IEnumerable<double> numbers)
=> numbers.Aggregate((a, b) => a + b);
static decimal Sum(IEnumerable<decimal> numbers)
=> numbers.Aggregate((a, b) => a + b);
// ✅ After: one method to rule them all
static T Sum<T>(IEnumerable<T> numbers)
where T : INumber<T>
=> numbers.Aggregate((a, b) => a + b);
C#: Math methods that work for ANY numeric type
with Generic Math & INumber<T>