1

Если есть 3 интерфейсы, такие как следующийDependency Injection Wireup Вопрос

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 */ 
} 
} 

Для сценария, как это, как бы вы wireup контейнер и что бы ваш метод тело выглядеть для BrutalKill и HonorKill?

EDIT: На основании комментариев я думал о линиях, где ниндзя должен быть вооружен оружием ... если он хочет быть вооруженным мечом или сюрикеном ... следует решить позже ... не уверен если я имею в виду право .. может быть, нам нужно создать подкласс ниндзя, как NinjaWithShuriken и NinjaWithSword

+0

Какие IoC вы используете? –

+3

Разве ваш ниндзя не нуждался бы в мече и инсурине? Я не понимаю, почему вы только что создали зависимость от IWeapon. –

+0

@Phil Sandler: Я думаю о том, что ниндзя должен быть вооружен оружием ... если он хочет быть вооруженным мечом или сюрикеном ... должно быть решено позже ... не уверен, что я думаю правильно – Perpetualcoder

ответ

3

Не уверен, если это то, что вы ищете, но я бы этот:

// 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>()); 

Обновление I как комментарий Фила Сандлера, так быстро обновить, чтобы это отразить:

// 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>(); 

Update Основываясь на обновление к первоначальному вопросу, я бы сказал:

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 
    } 
    ... 
} 

Идея заключается в том, что мы на самом деле не волнует, как Меч и Shuriken реализации атаки, до тех пор, ниндзя может использовать их для выполнения своего долга, когда его призывают. Убийство может быть каримым, как пожелает конкретный ниндек, пока работа выполняется в рамках указанного соглашения, в этом случае путем нападения.

// 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. MUCH предпочитает инъекцию конструктора над инъекцией сеттера. Я, скорее всего, разрешу Ninja через контейнер IOC (я понимаю, что он не реализовал какой-либо интерфейс, поэтому я понимаю, почему вы его оставили). –

1

Если ваш ниндзя способен BrutalKill и HonorableKill, он обязательно должен иметь ISword и IShuriken. Ninja зависит от них, поэтому мы объявляем их в CTOR:

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(); 
    } 
} 

Вот наше оружие:

public interface IWeapon 
{ 
    void Kill(); 
} 

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

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

Давайте получить пару реализаций этих зависимостей:

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!!!"); 
    } 
} 

Наша конфигурация выглядит следующим образом:

using Ninject.Modules; 

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

И наша точка входа выглядит следующим образом:

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

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

В единстве:

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

Если предположить, что Ninja имеет как Меч и Shuriken, так как только меч может порезать и только Shuriken может пробить.

Кроме того, у ниндзя есть конструктор, который принимает IShuriken и ISword в качестве аргументов.

И так, чтобы получить Ninja,

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

Kill(), без параметров, кажется, что вы командуете ниндзя совершить самоубийство.Я бы определил Ninja действовать на других ниндзя:

public interface INinja 
{ 
    void KillBrutally(INinja otherNinja); 

    void KillHonorably(INinja otherNinja); 
} 

Затем поднимите уровень абстракции от оружия, чтобы убить ход:

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

и Ниндзя поддерживают типы убийство:

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 
} 

Теперь мы можем беспокоиться об оружии:

и убить движется:

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 
} 

Вот пример проводки (переводим на ваш IoC контейнер по мере необходимости):

var sword = new Sword(); 

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

святая корова и повернула все на голову :) +1 – Perpetualcoder