An IoC container is typically useful to inject object that have state; or classes or interfaces that have more than one one implementation, even if the second implementation is a mock for testing purposes. If neither of these is true, you gain nothing by injecting it. the most common idiom these days is to have your class fronted by an interface that the real and mock implementation can both implement.
1) Static methods on helper classes - No, these do not often get injected by IoC. Typically they are stateless utilities.
To use a very simple example, you don't need two versions of a utility method called StringUtils.Reverse()
. You only need one, and you can easily write tests around it because it has no state or dependencies, so there's absolutely no benefit to mocking it out. Example test:
string reversedString = StringUtils.Reverse("input");
Assert.AreEqual("tupni", reversedString)
If the utility isn't really stateless (e.g. depends on HttpContext.Current), then you should make the dependency explicit by injecting it, and not making the utility static.
2) Singletons: Often yes, singletons are injected. But a good thing about IoC is that you worry less about whether there's only one of something or not. You gain flexibility in instancing by using IoC. The decision to have a particular type as singleton or new instance each time becomes part of the IoC container's config and nothing else in the code needs to change.
So singleton-hood stops being a separate concern that has to be coded into the class (and classes having multiple concerns when they don't have to is bad), and it becomes the concern of the IoC container. You don't code the class "as a singleton" with anything special like a private constructor and a public static GetInstance()
method any more, you just code it for the main concern, while the IoC container's config specifies if it's a singleton or not, or somewhere in between, like one instance per thread.
3) Static classes - are the natural home for static methods. Consider making the static methods extension methods where appropriate. You can't inject these classes, since you can't create them. Using static classes makes for procedural not object-oriented code. This isn't a bad thing for small helper methods, but if the majority of the code is like that, then you're not using the powerful OO features of the .Net platform.