gpt4 book ai didi

c# - 一个拿着剑的武士,一个拿着 Dagger 的武士

转载 作者:太空狗 更新时间:2023-10-29 23:16:06 25 4
gpt4 key购买 nike

感谢观看。我是 Ninject 的新手,到目前为止我很喜欢它。我得到了在 Debug模式下绑定(bind)一个东西并在 Release模式下绑定(bind)另一个东西的部分。这些是全局绑定(bind),您必须使用 Ninjects 示例代码声明每个武士都会有一把剑或 Dagger 。不是非此即彼,而是非此即彼。

我该怎么做才能让一个武士拿着剑,另一个武士拿着 Dagger ,他们甚至可以根据需要切换武器。除了创建一堆具有不同绑定(bind)模块的内核之外,还有其他方法吗?

这是来自 Ninject 的示例代码。如果将它放入控制台应用程序,它应该运行:

using System;
using Ninject;

namespace NinjectConsole
{
class Program
{

//here is where we have to choose which weapon ever samurai must use...
public class BindModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
//Bind<IWeapon>().To<Sword>();
Bind<IWeapon>().To<Shuriken>();
}
}

class Shuriken : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Pierced {0}'s armor", target);
}
}

class Sword : IWeapon
{
public void Hit(string target)
{
Console.WriteLine("Chopped {0} clean in half", target);
}
}

interface IWeapon
{
void Hit(string target);
}

class Samurai
{
readonly IWeapon weapon;

[Inject]
public Samurai(IWeapon weapon)
{
if (weapon == null)
throw new ArgumentNullException("weapon");

this.weapon = weapon;
}

public void Attack(string target)
{
this.weapon.Hit(target);
}
}

static void Main(string[] args)
{

//here is where we bind...
Ninject.IKernel kernel = new StandardKernel(new BindModule());

var samurai = kernel.Get<Samurai>();
samurai.Attack("your enemy");

//here is I would like to do, but with DI and no local newing up...
var warrior1 = new Samurai(new Shuriken());
var warrior2 = new Samurai(new Sword());
warrior1.Attack("the evildoers");
warrior2.Attack("the evildoers");
Console.ReadKey();
}
}
}

编辑

感谢您的回放和建议。

我想出了如何获得我想要的东西。好的,这就是我所做的:

  1. 将默认/初始绑定(bind)设置为最弱的武器。有点像 new-b 会做的。
  2. 添加了另一种武器( Dagger )
  3. 扩展了 IWeapon 以包含一个 WeaponHitPoints 值来评估武器值。
  4. 扩展了 Samurai 以包含添加和丢弃武器的方法,以便 Samurai 可以获得或失去武器。
  5. 修改了攻击方法以使用最好的武器。
  6. 修改程序以使用添加的功能。
  7. TODO:添加 try/catch 和 null 检查...

创建一个名为 NinjectConsole 的控制台项目,安装 Ninject,您应该能够将其放入并运行它。

这是新代码:

using System;
using System.Collections.Generic;
using System.Linq;
using Ninject;

namespace NinjectConsole
{
class Program
{
public class BindModule : Ninject.Modules.NinjectModule
{
// default bind to weakest weapon
public override void Load()
{
Bind<IWeapon>().To<Dagger>();
}
}

class Dagger : IWeapon
{
public int WeaponHitPoints { get { return 5; } }
public string Hit(string target)
{
return String.Format("Stab {0} to death", target);
}
}

class Shuriken : IWeapon
{
public int WeaponHitPoints { get { return 9; } }

public string Hit(string target)
{
return String.Format("Pierced {0}'s armor", target);
}
}

class Sword : IWeapon
{
public int WeaponHitPoints { get { return 11; } }

public string Hit(string target)
{
return string.Format("Chopped {0} clean in half", target);
}
}

interface IWeapon
{
int WeaponHitPoints { get; }
string Hit(string target);
}

private class Samurai
{
private IEnumerable<IWeapon> _allWeapons;

public Samurai(IWeapon[] allWeapons)
{
if (!allWeapons.Any())
throw new ArgumentException("Samurai");

_allWeapons = allWeapons;
}

public void AddWeapon(IWeapon weapon)
{ //TODO: check for nulls...
_allWeapons = _allWeapons.Concat(new[] { weapon });
}

public void DropWeapon(IWeapon weapon)
{ //TODO: check for nulls...
Console.WriteLine("A Samurai got rid of a " + weapon.WeaponName);

_allWeapons = _allWeapons.Where(x => x.WeaponName != weapon.WeaponName);
}

public void Attack(string target)
{
int points = 0;

try
{
points = _allWeapons.Max(x => x.WeaponHitPoints);
}
catch ()
{
Console.WriteLine("You just punched " + target + " on the nose!");
}

var attackWeapon = _allWeapons.FirstOrDefault(i => i.WeaponHitPoints == points);

//TODO: check for nulls...
Console.WriteLine(attackWeapon.Hit(target));
}
}

static void Main(string[] args)
{
Ninject.IKernel kernel = new StandardKernel(new BindModule());

var samurai1 = kernel.Get<Samurai>();
var samurai2 = kernel.Get<Samurai>();

Console.WriteLine("Samurai #1");
samurai1.Attack("your enemy");

samurai2.AddWeapon(new Shuriken());

Console.WriteLine("\nSamurai #2 selects best weapon for attack");
samurai2.Attack("your enemy");

Console.WriteLine("\nSamurai #1 gets new weapon!");
samurai1.AddWeapon(new Sword());

Console.WriteLine("Samurai #1 selects best weapon for attack");
samurai1.Attack("your enemy");

Console.ReadKey();
}
}
}

最佳答案

一般来说,您无法使用 IOC 容器实现这一点,除非您指定了一些条件,这些条件应该被满足以选择正确的实现(武器)。容器需要知道在当前情况下选择哪一种实现。

我建议,您正在寻找某种 Contextual binding .

Ninject 中有很多条件绑定(bind)方法(请在上面的链接中查看所有方法)。我选择了命名绑定(bind),因为它对于示例来说非常简单。

命名绑定(bind)

依赖项根据配置的名称解析。

kernel.Bind<Samurai>().ToSelf().Named("SwordMaster");
kernel.Bind<Samurai>().ToSelf().Named("ShurikenMaster");

kernel.Bind<IWeapon>().To<Sword>().WhenParentNamed("SwordMaster");
kernel.Bind<IWeapon>().To<Shuriken>().WhenParentNamed("ShurikenMaster");

warrior1 = kernel.Get<Samurai>("SwordMaster");
warrior2 = kernel.Get<Samurai>("ShurikenMaster");

多次注入(inject)

如果您希望您的 Samurai 能够处理多种武器,您可以为 IWeapon 声明多个绑定(bind),然后将这些绑定(bind)注入(inject) Samurai 作为一个集合。

public Samurai(IEnumerable<IWeapon> weapons)
{
this.AllMyWeapons = weapons;
}

关于c# - 一个拿着剑的武士,一个拿着 Dagger 的武士,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14737807/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com