Reputation: 835
I have a ninject problem where I am using the same interface on multiple types to provide a config class for my application.
The entry point classes (below) that start that application are returned from the ninject kernel and I have a named Config
dependency on that class.
public ProcessA(ILogger logger, [Named("TypeA")] IConfigProvider configProvider)
{
_logger = logger;
_configProvider = configProvider;
}
public ProcessB(ILogger logger, [Named("TypeB")] IConfigProvider configProvider)
{
_logger = logger;
_configProvider = configProvider;
}
And then in my bindings
Bind<IConfigProvider>().To<ProcessA>().Named("TypeA");
Bind<IConfigProvider>().To<ProcessB>().Named("TypeB");
Further down the processing line ProcessA
and ProcessB
share some classes that need an IConfigProvider
but when the ProcessA
or ProcessB
gets to that point ninject cannot resolve the dependancy. I can't make it a named dependency at that point because the classes are used by both processors.
I could pass the concrete Config
class down from ProcessA
and ProcessB
removing the constructor dependency but that doesn't seem the right way to do it.
I removed the named references and added the below which seems to do the trick. Found a method on the following question Ninject Bind When Ancestor Of Type T but I had to add in a check for request.Target == null
else it wouldnt work when I got an instance of ProcessA
and ProcessB
from the ninject kernel.
public override void Load()
{
Bind<IConfigProvider>()
.To<TypeAConfigProvider>()
.When(request => HasAncestorOfType<ProcessA>(request));
Bind<IConfigProvider>()
.To<TypeBConfigProvider>()
.When(request => HasAncestorOfType<ProcessB>(request));
}
private static bool HasAncestorOfType<T>(IRequest request)
{
if (request == null || request.Target == null)
return false;
if (request.Target.Member.ReflectedType == typeof(T))
return true;
return HasAncestorOfType<T>(request.ParentRequest);
}
Upvotes: 1
Views: 1686
Reputation: 13233
You can use the contextual binding mechanism to achieve that.
See IBindingWhenSyntax.cs for all available methods.
How about WhenAnyAncestorNamed
?
Alternatively, there's the WhenInjectedInto<>
binding which would be used like:
Bind<IConfigProvider>().To<ConfigA>()
.WhenInjectedInto<ProcessA>();
Now since you don't actually want to inject it directly into ProcessA
you'd have to use a When
condition like WhenInjectedIntoAncestor<Process>()
. You can create this yourself - as an extension method extending from the WhenAnyAncestorMatches
extension method. Also see here
Upvotes: 1