Привязать несколько интерфейсов к одной и той же реализации - PullRequest
0 голосов
/ 16 мая 2019

У меня есть дополнительный вопрос к этому вопросу: Можно ли привязать разные интерфейсы к одному и тому же экземпляру класса, реализующего все из них?

У меня есть сценарий, в котором один из интерфейсов должен быть разрешен по имени, предоставленному расширением «Named», а другой не нуждается в разрешении имени.

Например

public interface IMachine { }
public interface IDrillMachine : IMachine { }

public class Drill: IDrillMachine { }
public class ScrewDriver: IMachine { }

Ninject Binding

Bind<IMachine, IDrillMachine>().To<Drill>().Named("Drill");
Bind<IMachine>.To<ScrewDriver>().Named("ScrewDriver");

Инъекции

public class MachineConsumer
{
    public MachineConsumer([Named("Drill")]IMachine drillMachine)
    { }
}

public class DrillConsumer
{
    public DrillConsumer(IDrillMachine drillMachine)
    { }
}

Мой код не в рабочем состоянии, поэтому не могу проверить. Но я думаю, что во время разрешения IDrillMachine будет путаница, не так ли?

1 Ответ

0 голосов
/ 19 мая 2019

Это не сработает, потому что в конструкторе DrillConsumer отсутствует спецификация имени [Named("Drill")], но привязка для IDrillMachine требует этого. Ваш сценарий может быть разрешен двумя отдельными привязками для Drill:

Bind<IMachine>().To<Drill>().Named("Drill");
Bind<IDrillMachine>().To<Drill>();

Это немного сложнее, если Drill должен быть объектом области видимости, как синглтон. Добавление в InSingletonScope() к обоим привязкам приведет к двум случаям: одиночному для IMachine ("Drill") и одному для IDrillMachine.

Чтобы решить эту проблему, вы можете добавить уровень косвенности:

Bind<IMachine>().ToMethod(ctx => ctx.Kernel.Get<Drill>()).Named("Drill");
Bind<IDrillMachine>().ToMethod(ctx => ctx.Kernel.Get<Drill>());
Bind<Drill>().ToSelf().InSingletonScope();
...