I am using ninject.extensions.conventions
to bind all implementations in a given assembly and tag them with the assembly name as the binding's metadata. I can pull these items back out using a Get and supplying a func as standard.
What I would like to know is does this func apply to all children resolved also? My worry is that while my logic works now, if I add more bindings that satisfy any children more than once ninject will throw.
Code Sample:
_kernel.Bind(binder => binder.From(new[] { pathToAssembly })
.SelectAllClasses()
.BindAllInterfaces()
.Configure(binding =>
binding.WithMetadata("context",
assemblyName)));
_kernel.Get<IRootDependency>
(metadata => metadata.Get<IRootDependency>("context") ==
assemblyName);
// Bound from convention above.
RootDependencyBase: IRootDependency
{
Public RootDependencyBase(IChildDependency Child) {};
}
// Bound using the convention above with the same MetaData Tag.
ChildDependencyFromSameAssembly : IChildDependency {}
// Bound using a differing convention and does not have the same MetaData tag.
ChildDependencyFromOtherAssembly : IChildDependency {}
Based on the above sample I know that IRootDependency will be resolved to the correct binding based on the metadata filter.
What I am looking to find out is is the following true.
This filter does not feed down the dependency chain. IChildDependency will throw an exception because although the binding specified MetaData it is not queried.
Constraints are applyed to the root resolution only. In case you have multiple assemblies containing a child dependency you will get an exception.
To get it work you have to add a condition to the bindings. E.g like this:
.When(r => r.ParentContext == null || r.ParentContext.Binding.Metadata.Get<string>("context", null) == assemblyName)
Or get the root request (request.ParentRequest until parentRequest is null) and apply the constraint
.When(r => GetRootRequest(r).Constraint(r))