I've seen frameworks like Ninject as well as posts on Stack speak about self binding when using dependency injection frameworks like in the code below.
Bind<Samurai>().To<Samurai>();
They even go to the extent of having special syntax for this:
Bind<Samurai>().ToSelf();
Why would you want to bind a type to itself? I don't see any practical applications for where this might be useful and help reduce dependencies in code. Wouldn't this just mean a reference to a type would simply resolve to itself?
When applying Dependency Injection and adhering to the Dependency Inversion Principle the common advice is to program to interfaces, not implementations. That's why most of the time you'll see bindings that go from an abstraction to an implementation:
This means that components will take a dependency on
IWarrior
at compile time, and we inject aSamurai
at runtime.Under certain conditions however, it makes sense to have mapping from a concrete component to itself. In other words, in case 'someone' requests a
Samurai
, we supply it with thatSamurai
.The most prominent case is when resolving root types. Root types are the top of the Dependency Graph; root types are resolved directly from the container. All other types are direct or indirect dependencies of a root type.
Often you'll see that those root types are resolved by their concrete types and often we're dealing with UI frameworks. Examples of such are Web Forms
Page
s, MVCController
s, Web APIApiController
s, etc.Most DI containers allow concrete unregistered types to be resolved anyway. This might lead you to believe that a self-binding is redundant, but that is not always the case. Adding such binding explicitly lets the container know about the existence of such binding. This has the advantage of using the container's diagnostic abilities (if present) to scan the object graphs for errors. In case of the absence of such feature, one can usually iterate the known registrations and do some verification inside a unit test. For such verification to be meaningful when the container's registrations are iterated over, all root types need to be registered in the container. Otherwise this verification process will result in false-negatives.
Another reason why you want to tell the DI container about a self-binding is when the container doesn't allow resolving unregistered types, or when you need the type to be registered with a different lifestyle than the container's default lifestyle. Most containers will give you a Transient instance, in case the type isn't registered.