1

我正在研究与 Ninject 的上下文绑定。这适用于当您有一些抽象的多个实现时,并且注入目标类中的上下文确定注入哪些实现。

在文档中,使用“命名绑定”的示例如下所示:

Bind<IWeapon>().To<Shuriken>().Named("Strong");
Bind<IWeapon>().To<Dagger>().Named("Weak");

class WeakAttack {
    readonly IWeapon _weapon;
    public WeakAttack([Named("Weak")] IWeapon weakWeapon){
        _weapon = weakWeapon;
    }
    public void Attack(string victim){
        Console.WriteLine(_weapon.Hit(victim));
    }
}

这意味着包含的程序集WeakAttack显然必须引用 Ninject 才能NamedAttribute在构造函数中使用。依赖注入的目标不必知道使用了哪个 DI 容器。我在这里想念什么?

4

1 回答 1

3

一种方法是使用在目标程序集中定义的自定义属性:

public class BirdAttribute : Attribute { }
public class MonkeyAttribute : Attribute { }
public interface IAnimal { }
public class Bird : IAnimal { }
public class Monkey : IAnimal { }

在构造函数参数上使用自定义属性,例如:

public class BirdCage
{
    public BirdCage([Bird]IAnimal bird) => Bird = bird;
    public IAnimal Bird { get; }
}

public class Zoo
{
    public Zoo([Monkey]IAnimal monkey, [Bird]IAnimal bird)
    {
        Monkey = monkey;
        Bird = bird;
    }

    public IAnimal Monkey { get; }
    public IAnimal Bird { get; }
}

绑定将使用WhenTargetHas,如下所示:

internal class Module : NinjectModule
{
    public override void Load()
    {
        Bind<IAnimal>().To<Bird>().WhenTargetHas<BirdAttribute>();
        Bind<IAnimal>().To<Monkey>().WhenTargetHas<MonkeyAttribute>();
    }
}

这保持了控制反转的正确方向,因为带有 Ninject 绑定的程序集知道目标(即自定义属性),但目标不必知道正在使用哪个 IoC 容器。

于 2019-06-11T20:48:01.260 回答