Most people are familiar with the Singleton pattern. It was generally implemented and used as a static on steroids. Just calling Singleton.Instance.Foo(bar); meant that you couldn’t replace the implementation. You couldn’t mock it or extend it. This led to a backlash against the Singleton pattern. I always felt that this reputation had been earned unfairly.
I saw the implementation of the pattern as having the goal of there being one instance, but as a side effect of the implementation there is this globally accessible variable. That became the way the object was used. It was pulled in like using a service locator, but without even that little bit of indirection. There was this implicit dependency in the code you wrote on something, and it couldn’t be switched out. This was the big problem in my mind, not the global state.
This is why the Singleton lifestyle is so common in inversion of control containers. It gives you the positive aspects of the Singleton, without that unfortunate dependency. You could use a Singleton like a normal object by hand, but it would require a level of coding discipline that is hard to maintain. The Singleton lifestyle still has the global state, but it is abstracted away cleanly, thereby negating the worst of the associated side effects. Plus with the container you can just change the lifestyle if maintaining the Singleton aspect becomes too onerous for the benefits.
Reconsider the Singleton pattern. It may not be up there with some of the others in usefulness, but it is still a valuable tool in the toolbox.