I have two bindings:
Bind<ICache>().ToMethod(ctx => FactoryMethods.CreateCache(
ctx.Kernel.Get<IXXX>(),
ctx.Kernel.Get<IYYY>()))
.WhenTargetHas<SharedCacheAttribute>()
.InSingletonScope()
.Named(BindingNames.SHARED_CACHE);
Bind<ICache>().ToMethod(ctx => FactoryMethods.CreateTwoTierCache(
ctx.Kernel.Get<ICache>(BindingNames.SHARED_CACHE),
ctx.Kernel.Get<IZZZ>()))
.InSingletonScope();
Essentially the idea is that I have a shared cache (defined in first binding) but most of the time I want classes to use a two-tiered cache which is the same interface (ICache
). I therefore restrict use of the shared cache using an attribute constraint (classes that need direct access to the shared cache can just use [SharedCache]
).
Now, the problem is that the second binding, specifically this line:
ctx.Kernel.Get<ICache>(BindingNames.SHARED_CACHE),
is throwing an exception that no matching bindings are available, presumably because of the attribute constraint on the first binding.
How can I inject the resolution result of the first binding into the second binding's factory method?
Workaround:
Currently I am using a Parameter
and a more complex When()
-based constraint on the first binding. My bindings now look like this:
Bind<ICache>().ToMethod(ctx => FactoryMethods.CreateCache(
ctx.Kernel.Get<IXXX>(),
ctx.Kernel.Get<IYYY>()))
.When(o => (o.Target != null &&
o.Target.GetCustomAttributes(typeof (SharedCacheAttribute), false).Any()) ||
o.Parameters.Any(p => p.Name == ParameterNames.GET_SHARED_CACHE))
.InSingletonScope();
Bind<ICache>().ToMethod(ctx => FactoryMethods.CreateTwoTierCache(
ctx.Kernel.Get<ICache>(new Parameter(ParameterNames.GET_SHARED_CACHE, true, true)),
ctx.Kernel.Get<IZZZ>()))
.InSingletonScope();
It works as intended, but the syntax is crazy complicated. Also, I would have expected the 'shouldInherit' argument of the Parameter
constructor to have to be set to false
to prevent the GET_SHARED_CACHE parameter from being passed to child requests. As it happens, setting this to false
ends up causing a StackOverflowException
as the parameter is persisted across requests when this is set to false. Setting it to true
causes it to not propagate - the opposite of what I would have expected.