1

S'il y a 3 interfaces comme leinjection de dépendances Wireup Question

public interface IWeapon { 
void Kill(); 
} 

public interface ISword:IWeapon { 
void Slice(); 
} 

public interface IShuriken: IWeapon { 
void Pierce(); 
} 

public class Ninja { 
public IWeapon Weapon {get;set;} 
public void BrutalKill() { 

/* warrior must pierce, pierce, pierce and then kill 


*/ 

} 
public void HonorKill { 
/* warrior must kill by one slice */ 
} 
} 

Pour un tel scénario comment vous wireup suivant le conteneur et à quoi ressemblerait votre corps de méthode comme pour BrutalKill et HonorKill? D'après les commentaires, je pensais aux lignes qu'un ninja devrait être armé d'une arme ... s'il veut être armé d'une épée ou d'un shuriken ... devrait être décidé plus tard ... je ne suis pas sûr si je pense bien .. peut-être nous avons besoin de sous-classe Ninja comme NinjaWithShuriken et NinjaWithSword

+0

Quelle IoC utilisez-vous? –

+3

Votre ninja n'aurait-il pas besoin d'un ISword et d'un IShuriken injecté? Je ne comprends pas pourquoi vous avez seulement fait une dépendance pour IWeapon. –

+0

@Phil Sandler: Je pense aux lignes qu'un ninja devrait être armé d'une arme ... s'il veut être armé d'une épée ou d'un shuriken ... devrait être décidé plus tard ... je ne sais pas si je pense bien – Perpetualcoder

Répondre

3

Je ne sais pas si cela est ce que vous cherchez, mais j'aurais ceci:

// first some implementations 
public class Sword : ISword { 
    public void Kill() { // imp } 
    public void Slice() { // imp } 
} 

public class Shuriken : IShuriken { 
    public void Kill() { // imp } 
    public void Pierce() { // imp } 
} 

// and I would change the Ninja class to 
public class Ninja { 
    public ISword Sword { get; private set; } 
    public IShuriken Shuriken { get; private set; } 

    public Ninja(ISword sword, IShuriken shuriken) { 
     this.Sword = sword; 
     this.Shuriken = shuriken; 
    } 

    public void BrutalKill() { 
     Shuriken.Pierce(); 
     Shuriken.Pierce(); 
     Shuriken.Pierce(); 

     // either weapon can kill 
     // so lets close the distance and use the sword 
     Sword.Kill(); 
    } 

    public void HonorKill { 
     Sword.Slice(); 
    } 
} 

// creating the class 
// where Ioc.Resolve is specific to the container implementation 
var ninja = new Ninja(IoC.Resolve<ISword>(), IoC.Resolve<IShuriken>()); 

Mise à jour I comme le commentaire de Phil Sandler donc une mise à jour rapide pour refléter cela:

// a ninja interface 
public interface INinja { 
    void BrutalKill(); 
    void HonorKill(); 
} 

// and then update the ninja class to 
public Ninja : INinja { 
    ... 
} 

// and have the ninja class created like this with the container 
// resolving the dependencies: 
var ninja = IoC.Resolve<INinja>(); 

Mise à jour Sur la base de la mise à jour à la question initiale, je dirais:

public interface IWeapon { 
    void Attack(); 
    void Kill(); 
} 

public class Sword : ISword { 
    public void Attack() { 
     // implement as a slash 
    } 
    ... 
} 

public class Shuriken : IShuriken { 
    public void Attack() { 
     // implement as a pierce 
    } 
    ... 
} 

L'idée étant que nous ne nous soucions pas vraiment comment l'épée et Shuriken mettre en œuvre d'attaque, aussi longtemps que le ninja peut les utiliser pour accomplir son devoir lorsqu'il est appelé. L'assassinat peut être expliqué comment le ninject spécifique souhaite, tant que le travail se fait dans les limites de l'accord déclaré, dans ce cas par Attaquer.

// create the specific ninja 
var swordNinja = new Ninja(IoC.Resolve<ISword>()); 
var shurikenNinja = new Ninja(IoC.Resolve<IShuriken>()); 

// with the ninja class updated to only have an IWeapon 
// property that gets set in the constructor. 
+0

+1. BEAUCOUP préfère l'injection du constructeur plutôt que l'injection du setter. Je résoudrais probablement Ninja via le conteneur IOC (je réalise qu'il n'a pas implémenté d'interface, alors je comprends pourquoi vous l'avez laissé). –

1

Si votre ninja est capable de BrutalKill et HonorableKill, il faut absolument avoir un ISword et un IShuriken. Ninja dépend de ceux-ci, donc nous les déclarer dans le cteur:

public class Ninja 
{ 
    readonly IShuriken shuriken; 
    readonly ISword sword; 

    public Ninja(IShuriken sh, ISword sw) 
    { 
     shuriken = sh; 
     sword = sw; 
    } 

    public void BrutalKill() 
    { 
     shuriken.Pierce(); 
     shuriken.Pierce(); 
     shuriken.Pierce(); 
     sword.Slice(); 
     shuriken.Kill(); 
    } 

    public void HonorKill() 
    { 
     sword.Slice(); 
     sword.Kill(); 
    } 
} 

Voilà nos armes:

public interface IWeapon 
{ 
    void Kill(); 
} 

public interface IShuriken : IWeapon 
{ 
    void Pierce(); 
} 

public interface ISword : IWeapon 
{ 
    void Slice(); 
} 

Entrons une mise en oeuvre d'un couple de ces dépendances:

using System; 

public class BronzeShuriken : IShuriken 
{ 
    public void Pierce() 
    { 
     Console.WriteLine("Bronze shuriken pierce time now!"); 
    } 

    public void Kill() 
    { 
     Console.WriteLine("Bronze shuriken kill!!!"); 
    } 
} 

public class RustySword : ISword 
{ 
    public void Slice() 
    { 
     Console.WriteLine("Rusty sword slice time now!"); 
    } 

    public void Kill() 
    { 
     Console.WriteLine("Rusty sword kill!!!"); 
    } 
} 

Notre configuration ressemble à ceci:

using Ninject.Modules; 

class DefaultModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<IShuriken>().To<BronzeShuriken>(); 
     Bind<ISword>().To<RustySword>(); 
    } 
} 

Et notre point d'entrée ressemble à ceci:

static void Main() 
    { 
     using (var kernel = new StandardKernel()) 
     { 
      kernel.Load(new DefaultModule()); 

      kernel.Get<Ninja>().BrutalKill(); 
     } 
    } 
0

Dans l'unité:

Container.RegisterType<INinja,Ninja>(); 
Container.RegisterType<ISword,Sword>(); 
Container.RegisterType<IShuriken,Shuriken>(); 

En supposant que Ninja a à la fois l'épée et Shuriken depuis que l'épée peut couper et seulement Shuriken peut percer.

En outre, Ninja a un constructeur qui accepte IShuriken et ISword comme arguments.

Et pour obtenir Ninja,

var ninja= Container.Resolve<INinja>(); 
1

Kill(), sans paramètre, semble que vous commandons le ninja à se suicider.Je définirais Ninja d'agir sur d'autres ninjas:

public interface INinja 
{ 
    void KillBrutally(INinja otherNinja); 

    void KillHonorably(INinja otherNinja); 
} 

Ensuite, élever le niveau d'abstraction de l'arme pour tuer mouvement:

public interface IKillMove 
{ 
    void Kill(INinja ninja); 
} 

et ont des ninjas en charge les types de kill:

public sealed class Ninja : INinja 
{ 
    private readonly IKillMove _brutalKillMove; 
    private readonly IKillMove _honorableKillMove; 

    public Ninja(IKillMove brutalKillMove, IKillMove honorableKillMove) 
    { 
     _brutalKillMove = brutalKillMove; 
     _honorableKillMove = honorableKillMove; 
    } 

    #region INinja 

    public void KillBrutally(INinja otherNinja) 
    { 
     _brutalKillMove.Kill(otherNinja); 
    } 

    public void KillHonorably(INinja otherNinja) 
    { 
     _honorableKillMove.Kill(otherNinja); 
    } 
    #endregion 
} 

Maintenant, nous pouvons nous soucier des armes:

public interface IWeapon 
{ 
    void Attack(INinja ninja); 

    void Finish(INinja ninja); 
} 

et tuer mouvements:

public sealed class MoveInKillMove : IKillMove 
{ 
    private readonly IWeapon _shortRangeWeapon; 
    private readonly IWeapon _longRangeWeapon; 

    public MoveInKillMove(IWeapon shortRangeWeapon, IWeapon longRangeWeapon) 
    { 
     _shortRangeWeapon = shortRangeWeapon; 
     _longRangeWeapon = longRangeWeapon; 
    } 

    #region IKillMove 

    public void Kill(INinja ninja) 
    { 
     _longRangeWeapon.Attack(ninja); 
     _longRangeWeapon.Attack(ninja); 
     _longRangeWeapon.Attack(ninja); 

     _shortRangeWeapon.Finish(ninja); 
    } 
    #endregion 
} 

public sealed class FinishingMove : IKillMove 
{ 
    private readonly IWeapon _weapon; 

    public FinishingMove(IWeapon weapon) 
    { 
     _weapon = weapon; 
    } 

    #region IKillMove 

    public void Kill(INinja ninja) 
    { 
     _weapon.Finish(ninja); 
    } 
    #endregion 
} 

Voici un câblage de l'échantillon (Traduisez à votre conteneur IoC si nécessaire):

var sword = new Sword(); 

var ninja = new Ninja(
    new MoveInKillMove(sword, new Shuriken()), 
    new FinishingMove(sword)); 
+0

la vache sacrée vous avez tourné le tout sur sa tête :) +1 – Perpetualcoder