依赖注入接线问题

发布于 2024-08-15 10:53:44 字数 591 浏览 6 评论 0原文

如果有如下 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

If there are 3 interfaces like the following

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

For a scenario like this how would you wireup the container and what would your method body look like for BrutalKill and HonorKill ?

EDIT: Based on comments, I was thinking on the lines a ninja should be armed with a weapon... if it wants to be armed with a sword or shuriken...should be decided later... not sure if i am thinking right .. maybe we need to subclass Ninja as NinjaWithShuriken and NinjaWithSword

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

你列表最软的妹 2024-08-22 10:53:44

不确定这是否是您要找的,但我想要这个:

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

我们的想法是,我们并不真正关心剑和手里剑如何实施攻击,只要忍者在需要时可以使用它们来履行他的职责。暗杀可以按照特定忍者的意愿进行,只要工作在规定的协议范围内完成,在这种情况下是通过攻击。

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

Not sure if this is what you are looking for, but I would have this:

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

Update
I like Phil Sandler's comment so a quick update to reflect that:

// 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
Based on the update to the original question I would say:

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

The idea being that we don't really care how Sword and Shuriken implement Attack, as long as the ninja can use them to perform his duty when called upon. The assassination can be caried out how the specific ninject wishes, as long as the job gets done within the confines of the stated agreement, in this case by Attacking.

// 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.
辞取 2024-08-22 10:53:44

如果你的忍者能够进行残酷杀戮和荣耀杀戮,他绝对必须拥有ISword和ISShuriken。 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();
        }
    }

If your ninja is able to BrutalKill and HonorableKill, he absolutely must have a ISword and a IShuriken. Ninja is dependent on these, so we declare them in the 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();
    }
}

Here's our weapons:

public interface IWeapon
{
    void Kill();
}

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

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

Let's get a couple implementations of these dependencies:

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

Our configuration looks like this:

using Ninject.Modules;

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

And our entry point looks like this:

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

            kernel.Get<Ninja>().BrutalKill();
        }
    }
何处潇湘 2024-08-22 10:53:44

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

Kill(), with no parameters, seems like you are commanding the ninja to commit suicide. I would define Ninja to act on other ninjas:

public interface INinja
{
    void KillBrutally(INinja otherNinja);

    void KillHonorably(INinja otherNinja);
}

Then, raise the level of abstraction from weapon to kill move:

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

and have ninjas support the kill types:

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
}

Now we can worry about weapons:

public interface IWeapon
{
    void Attack(INinja ninja);

    void Finish(INinja ninja);
}

and kill moves:

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
}

Here is a sample wiring (translate to your IoC container as necessary):

var sword = new Sword();

var ninja = new Ninja(
    new MoveInKillMove(sword, new Shuriken()),
    new FinishingMove(sword));
秋风の叶未落 2024-08-22 10:53:44

统一:

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

假设忍者同时拥有剑和手里剑,因为只有剑可以切片,只有手里剑可以刺穿。

此外,Ninja 有一个接受 IShuriken 和 ISword 作为参数的构造函数。

所以为了获得忍者,

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

In unity:

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

Assuming that Ninja has both Sword and Shuriken since only Sword can slice and only Shuriken can pierce.

Also, Ninja has a constructor that accepts IShuriken and ISword as arguments.

And so to get Ninja,

var ninja= Container.Resolve<INinja>();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文