I presume that when you say a "DateTime wrapper" what you really mean is a "Clock" interface which can be queried for the DateTime value which humans occasionally perceive as "now".
I too have encountered the problem of having to pass my dependencies around a lot, and I have solved it with a universal lightweight adaptation of Domain Driven Design instead of a Service Locator. (I don't like service locators precisely because, as JDT pointed out, they may defer a compile-time error to a run-time error.)
The idea is this:
Every object ideally belongs to a domain. In this case, it is called a subject of that domain.
A domain is the exclusive factory of its subjects. Nobody else may instantiate a subject. This in turn means that all subject constructors are hidden to the outside world. (Package-private in java.)
Every subject receives a reference to the domain to which it belongs as its first constructor parameter. (This is analogous to how every method of an object receives the
this pointer as its first (hidden) parameter.)
Every subject that needs some kind of service obtains it from its own domain via a property. (Regular getXYZ(), no map lookup.)
The domain may offer a service directly, (as in
myDomain.getGradientSaturator()) or indirectly (as in
Ideally, subjects are visible to outside code (code outside the namespace or package of their domain) via interfaces, not as concrete classes. (But this is irrelevant to this discussion.)
Domains receive their dependencies as constructor parameters.
Nobody needs to query any repository for services, no huge lists of dependencies are passed either to constructors or to factory methods, (except perhaps to constructors of domains, which are rare,) and the availability of all services is guaranteed (so to speak*) by the compiler.
Still, at various places where domain hierarchies are constructed, all necessary services are supplied, so any one of them can be replaced with a mock.
In lack of any better term, I am calling this Subject-Oriented Programming for the time being.
(*) so to speak, unless you do something silly, like pass
null to a constructor which expected a