The old adage "program to an abstraction, not a concretion" reigns true and used in most modern application design via the use of Interfaces and concepts like IoC and DI. The polymorphic behavior of Interfaces and their ability to have multiple implementations allows us to do some really cool things as well as be staged for highly testable code with mocking frameworks like Moq.
However I'd say 99% of the time we typically have 1 Interface bound to a single concrete class using our DI framework. There will be cases where you will want to take advantage of having more than 1 implementation of an Interface and need to configure this.
Ninject is a great DI framework and you can achieve this through the use of named bindings. In this case if we have an Interface named ICalculate you could have 2 (or more) implementations. However upon injecting the class into a constructor, how would you dictate which instantiation/binding to use? The named bindings accomplish this as follows.
1. Provide a name for the bindings using the same Interface to allow them to be unique:
2. Specify the named binding as an attribute applied on the argument of the Interface being injected:
It's that easy! For more information, see the Ninject documentation here.
However I'd say 99% of the time we typically have 1 Interface bound to a single concrete class using our DI framework. There will be cases where you will want to take advantage of having more than 1 implementation of an Interface and need to configure this.
Ninject is a great DI framework and you can achieve this through the use of named bindings. In this case if we have an Interface named ICalculate you could have 2 (or more) implementations. However upon injecting the class into a constructor, how would you dictate which instantiation/binding to use? The named bindings accomplish this as follows.
1. Provide a name for the bindings using the same Interface to allow them to be unique:
Bind<ICalculate>().To<CalcImpl1>().Named("Calculation1"); Bind<ICalculate>().To<CalcImpl2>().Named("Calculation2");
2. Specify the named binding as an attribute applied on the argument of the Interface being injected:
readonly ICalculate _calculate; public MathCalculations([Named("Calculation1")] ICalculate calculate){ _calculate = calculate; }
It's that easy! For more information, see the Ninject documentation here.