3

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?

oflad
  • 78
  • 7
  • It is just making the framework aware of the object to be resolved. For example `Bind().ToSelf().InSingletonScope();` lets the container know that the type should be resolved as a singleton. All in all this is just part of registering types with the container. – Nkosi Jan 04 '17 at 02:39
  • But why does it need to be resolved? if we are passing the instance into the constructor I don't see the need to resolve it. Also is `.InSingletonScope()` used so we don't have to implement the singleton pattern ourselves? – oflad Jan 04 '17 at 02:45
  • because the container is what instantiates the instances and it needs to be aware of what types it can create adn how to deal/handle them. Do you understand dependency inversion principle? the whole point of the container is to not to have to do it yourself – Nkosi Jan 04 '17 at 02:46
  • but whats the purpose of using a container if you're binding a type to itself? In this case is the framework actually doing anything? – oflad Jan 04 '17 at 02:49
  • You are focusing on the wrong thing and confusing the concepts. and it is too broad to go through all the semantics here. you need to read up on DI (which actually mean dependency inversion, not dependency injection like most people think) and grasp/understand the concept of the dependency injection container ( which is an implementation of dependency inversion). – Nkosi Jan 04 '17 at 02:54
  • tl;dr; - normally you bind implementation to abstractions. if implementation has no abstractions then it binds to itself. so that container knows what to so when asked for the type – Nkosi Jan 04 '17 at 02:56

1 Answers1

7

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:

Bind<IWarrior>().To<Samurai>();

This means that components depend on IWarrior at compile time, while you inject a Samurai at runtime.

Under certain conditions, however, it makes sense to have mapping from a concrete component to itself. In other words, in case 'someone' requires a Samurai, you supply it with that Samurai.

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 components are direct or indirect dependencies of a root type.

Often you'll see that those root types are resolved by their concrete types and this happens, for instance, when dealing with UI frameworks. Examples of such are Web Forms Pages, MVC Controllers, Web API ApiControllers, etc.

Some DI containers allow concrete unregistered types to be resolved anyway (although in recent years several DI Containers for .NET have disabled the ability to resolve concrete unregistered types by default). 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 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.

Steven
  • 166,672
  • 24
  • 332
  • 435