如果有3个界面,如下所示
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 */
}
}
对于这样的场景,你会如何对容器进行连接以及你的方法体对于BrutalKill和HonorKill会是什么样的?
编辑:根据评论,我正在思考一个忍者应该携带武器......如果它想要武装剑或手里剑...应该稍后决定......不确定是否我正在思考..也许我们需要将Ninja子类化为NinjaWithShuriken和NinjaWithSword答案 0 :(得分: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>());
<强>更新强> 我喜欢Phil Sandler的评论,所以快速更新以反映:
// 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>();
<强>更新强> 根据对原始问题的更新,我会说:
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
}
...
}
我们并不真正关心Sword和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.
答案 1 :(得分:1)
如果你的忍者能够获得BrutalKill和HonorableKill,他绝对必须拥有一个ISword和一个IShuriken。忍者依赖于这些,所以我们在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();
}
}
答案 2 :(得分:1)
Kill()
,没有参数,似乎是在命令忍者自杀。我会定义Ninja
来对其他忍者采取行动:
public interface INinja
{
void KillBrutally(INinja otherNinja);
void KillHonorably(INinja otherNinja);
}
然后,提高武器的抽象等级来杀死移动:
public interface IKillMove
{
void Kill(INinja ninja);
}
让ninjas支持杀戮类型:
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 interface IWeapon
{
void Attack(INinja ninja);
void Finish(INinja ninja);
}
并杀死动作:
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));
答案 3 :(得分:0)
团结一致:
Container.RegisterType<INinja,Ninja>();
Container.RegisterType<ISword,Sword>();
Container.RegisterType<IShuriken,Shuriken>();
假设Ninja同时拥有Sword和Shuriken,因为只有Sword可以切片且只有Shuriken可以刺穿。
此外,Ninja有一个接受IShuriken和ISword作为参数的构造函数。
所以要忍者,
var ninja= Container.Resolve<INinja>();