Приветствую многоуважаемое сообщество Тостера.
Недавно открыл для себя Dependency Injection. Прочитал кучу статей на эту тему в инете, но так и не понял, в чем его прелесть. Решил разобраться на практическом примере. Допустим, есть у нас некое подобие игры, в которой мы имеем дело с юнитами-солдатами. У солдат есть оружие. Общее описание оружия содержится в интерфейсе IWeapon:
public interface IWeapon
{
int Ammo { get; set; }
string Name { get; }
void Fire();
}
Общее описание солдата хранится в интерфейсе ISoldier:
public interface ISoldier
{
string Type { get; }
IWeapon Weapon { get; set; }
void Move();
}
Есть две реализации интерфейса IWeapon: AssaultRifle и MachineGun. Соответственно, есть две реализации интерфейса ISoldier: Rifleman и MachineGunner. Задание оружия для них выполняется в их конструкторах следующим образом:
public class Rifleman : ISoldier
{
private IWeapon _weapon;
public Rifleman()
{
_weapon = new AssaultRifle();
}
...
}
public class MachineGunner : ISoldier
{
private IWeapon _weapon;
public MachineGunner()
{
_weapon = new MachineGun();
}
...
}
Так создание экземпляров классов и их использование выглядит в функции Main():
//Классический случай
ISoldier rifleman = new Rifleman();
ISoldier machineGunner = new MachineGunner();
for (int i = 0; i < 10; i++)
{
rifleman.Weapon.Fire();
machineGunner.Weapon.Fire();
}
Если же использовать Dependency Injection через тот же Ninject, то вот как мне придется это делать:
public class AssaultRifleConfigModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<AssaultRifle>();
}
}
public class MachineGunConfigModule : NinjectModule
{
public override void Load()
{
Bind<IWeapon>().To<MachineGun>();
}
}
public class RiflemanConfigModule : NinjectModule
{
public override void Load()
{
Bind<ISoldier>().To<Rifleman>();
}
}
public class MachineGunnerConfigModule : NinjectModule
{
public override void Load()
{
Bind<ISoldier>().To<MachineGunner>();
}
}
public class Rifleman : ISoldier
{
...
public Rifleman()
{
IKernel weaponKernel = new StandardKernel(new AssaultRifleConfigModule());
_weapon = weaponKernel.Get<IWeapon>();
}
...
}
public class MachineGunner : ISoldier
{
...
public MachineGunner()
{
IKernel weaponKernel = new StandardKernel(new MachineGunConfigModule());
_weapon = weaponKernel.Get<IWeapon>();
}
...
}
...
static void Main(string[] args)
{
...
//DI через NInject
IKernel soldierKernel = new StandardKernel(new RiflemanConfigModule());
ISoldier rifleman = soldierKernel.Get<ISoldier>();
soldierKernel = new StandardKernel(new MachineGunnerConfigModule());
ISoldier machineGunner = soldierKernel.Get<ISoldier>();
for (int i = 0; i < 10; i++)
{
rifleman.Weapon.Fire();
machineGunner.Weapon.Fire();
}
}
Вопрос: чем способ с применением Dependency Injection лучше использования оператора new в данной ситуации?