Перепривязать косвенную зависимость с помощью ninject childkernel

Я использую Ninject и Ninject.Extensions.ChildKernel.

У меня есть следующие интерфейсы IService и IServiceProvider

Моя реализация IServiceProvider использует экземпляр IService

public interface IServiceProvider
{
    IService Service { get; }
}
public class ServiceProvider : IServiceProvider
{
    public ServiceProvider(IService service)
    {
        this.Service = service;
    }
    public IService Service { get; private set; }
}

Сейчас делаю следующее

var container = new StandardKernel();
container.Bind<IService>().To<Service>();
container.Bind<IServiceProvider>.To<ServiceProvider>();

// later in code
var child = new ChildKernel(container);
child.Bind<IService>().To<ChildService>();

var provider = child.Get<IServiceProvider>();
var serviceA = provider.Service;      // <-- Service
var serviceB = child.Get<IService>(); // <-- ChildService

Как видите, child.Get<IService>() работает, как и ожидалось, и возвращает ChildService, но я также хочу, чтобы каждый экземпляр IServiceProvider, созданный с дочерним ядром, использовал ChildService. Возможно ли это с Ninject.Extensions.ChildKernel

Обратите внимание: я уже публиковал это в Ninject.Extensions.ChildKernel системе отслеживания проблем, но я даже не уверен, что это проблема, или я просто использую его неправильно.


person Jürgen Steinblock    schedule 27.11.2015    source источник


Ответы (1)


Это не поддерживается.

Вот как работает дочернее ядро ​​(насколько мне известно TM): если вы запрашиваете тип у дочернего ядра, оно сначала проверяет свои собственные привязки, чтобы увидеть, может ли оно его удовлетворить. Если это возможно, он вернет значение (при необходимости создав экземпляр и зависимости). Если у дочернего ядра нет привязки, которая удовлетворяет запросу, оно попросит родительское ядро ​​разрешить его и возвратит результат родительского ядра.

  • В вашем дочернем ядре нет привязки для IServiceProvider
  • Таким образом, запрос перенаправляется в родительское ядро ​​для разрешения.
  • Родительское ядро ​​имеет привязку для IService, оно создает ее на основе привязок, известных родительскому ядру - родительское ядро ​​не знает о дочернем ядре и привязках дочернего ядра. Он даже не знает, что запрос поступил от дочернего ядра.
  • дочернее ядро ​​возвращает IServiceProvider и IService - оба разрешаются из родительского ядра.

Короче говоря: если вы хотите, чтобы дочернее ядро ​​разрешало IServiceProvider, вам нужно добавить привязку для IServiceProvider к дочернему ядру.

person BatteryBackupUnit    schedule 27.11.2015
comment
Спасибо за подробное объяснение. В реальном мире я использую Nancy с Nancy.BootStrappers.Ninject, которые используют дочернее ядро ​​​​для каждого запроса, и я не могу перепривязать IServiceProvider интерфейс, который я перепривязываю, может использоваться или не использоваться как косвенная зависимость. Есть ли другие способы обойти это? - person Jürgen Steinblock; 27.11.2015
comment
я дважды проверил, и пока вы не можете добавить привязки к дочернему ядру, я не вижу способа обойти это. Во-первых, лучше использовать области (например, NamedScope), чем Childkernels с Ninject... возможно, поэтому в любом случае нет идеальной поддержки ChildKernel. - person BatteryBackupUnit; 27.11.2015