Один из способов сделать это - с помощью пользовательских атрибутов, определенных в целевой сборке:
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 используется.