Ninject inject dependency based on the controller

182 views Asked by At

I am using Ninject in my web api. I have a following problem. Let's say there are two api controllers (ControllerA and ControllerB). Both are dependent on MyClass and MyClass depends on ClientFactory and ClientFactory depends on Resolver.

public class MyClass
{
    public MyClass(IClientFactory clientFactory)
    { ... }
}

public interface IClientFactory
{
   Client CreateClient();
}

public class ClientFactory : IClientFactory
{
    private readonly IResolver _resolver;
    public ClientFactory(IResolver resolver)
    { 
        _resolver = resolver; 
    }

    ...
}

public class ResolverA : IResolver
{
}

public class ResolverB : IResolver
{
}

public ControllerA : ApiController
{
   public ControllerA(MyClass myClass)
   {
    ...
   }
}

public ControllerB : ApiController
{
    public ControllerB(MyClass myClass)
    {
       ...
    }
}

I would like to use ResolverA in ClientFactory when MyClass is injected into ControllerA and ResolverB in ClientFactory when MyClass is injected into ControllerB. Can that be configured with Ninject?

Thank you.

1

There are 1 answers

0
BatteryBackupUnit On BEST ANSWER

It can (the keyword is "contextual binding", which is documented in the ninject wiki here). However your specific use case is not supported out of the box. There is .WhenIsInjectedInto<T>, but that's no good since in your case the direct parent is always MyClass (you're looking for something like .WhenHasAncestorOfType<T>()). So you have to roll your own:

kernel.Bind<IResolver>()
    .To<ResolverA>()
    .WhenAnyAncestorMatches(x => x.Binding.Service == typeof(ControllerA));

kernel.Bind<IResolver>()
    .To<ResolverB>()
    .WhenAnyAncestorMatches(x => x.Binding.Service == typeof(ControllerB));

Of course depending on how the Controller is actually requested you might have to adapt the x.Binding.Service == typeof(...) part. You can also look into the implementation of .WhenIsInjectedInto for ideas / guidance.