Jürgen Steinblock
Jürgen Steinblock

Reputation: 31743

Rebind indirect depdendency with ninject childkernel

I am using Ninject and Ninject.Extensions.ChildKernel

I have the following interfaces IService and IServiceProvider

My IServiceProvider implementation takes an IService instance

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

Now I do the following

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

As you can see child.Get<IService>() works as expected and returns ChildService but I also want every instance of IServiceProvider contructed with the child kernel to use ChildService. Is this possible with Ninject.Extensions.ChildKernel

Please note: I already posted this on the Ninject.Extensions.ChildKernel issue tracker but I am not even sure if this is an issue or I am just using it wrong.

Upvotes: 1

Views: 920

Answers (1)

BatteryBackupUnit
BatteryBackupUnit

Reputation: 13243

It's not supported.

This is how the child kernel works (to my knowledge TM): If you ask for a type from the child kernel, it first checks it's own bindings to see whether it can satisfy it. If it can, it will return the value (constructing an instance and dependencies if necessary). If the child kernel doesn't have a binding which satisfies the request, it will ask the parent kernel to resolve it and return the result of the parent kernel.

  • Your child kernel doesn't have a binding for IServiceProvider
  • The request is thus forwarded to the parent kernel for resolution
  • The parent kernel does have a binding for IService, it constructs it based on the bindings the parent kernel knows - the parent kernel does not know about the child kernel and the child kernel's bindings. It doesn't even know the request came from a child kernel.
  • the child kernel returns IServiceProvider and IService - both resolved from the parent kernel.

Long story short: If you want the child kernel to resolve the IServiceProvider you need to add a binding for IServiceProvider to the child kernel.

Upvotes: 2

Related Questions