Reputation: 24482
What would the following example look like re-written to use Ninject?
Specifically how would you bind a Samurai to both Shuriken and Sword?
(From https://github.com/ninject/ninject/wiki/Dependency-Injection-By-Hand)
interface IWeapon
{
void Hit(string target);
}
class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}
class Shuriken : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Pierced {0}'s armor", target);
}
}
class Program
{
public static void Main()
{
var warrior1 = new Samurai(new Shuriken());
var warrior2 = new Samurai(new Sword());
warrior1.Attack("the evildoers");
warrior2.Attack("the evildoers");
/* Output...
* Piereced the evildoers armor.
* Chopped the evildoers clean in half.
*/
}
}
Upvotes: 0
Views: 137
Reputation: 7088
You could simply rebind IWeapon
after resolving first Samurai
:
StandardKernel kernel = new StandardKernel();
kernel.Bind<IWeapon>().To<Sword>().Named();
Samurai samurai1 = kernel.Get<Samurai>();
samurai1.Attack("enemy");
kernel.Rebind<IWeapon>().To<Shuriken>();
Samurai samurai2 = kernel.Get<Samurai>();
samurai2.Attack("enemy");
Alternatively, you could use named bindings. It would be first necessary to redefine Samurai
's constructor a bit, adding a Named
attribute to its dependency:
public Samurai([Named("Melee")]IWeapon weapon)
{
this.weapon = weapon;
}
Then, you would need to give names to your bindings as well:
StandardKernel kernel = new StandardKernel();
kernel.Bind<IWeapon>().To<Sword>().Named("Melee");
kernel.Bind<IWeapon>().To<Shuriken>().Named("Throwable");
Samurai samurai = kernel.Get<Samurai>();
samurai.Attack("enemy"); // will use Sword
There are really many alternatives - I would recommend browsing over the link provided by @scottm and checking them all out.
Upvotes: 2