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))

其他提示

Yes, in case if your examples will has another implementation of IChildDependency in same assembly as ChildDependencyFromSameAssembly you'll get exception ActivationException with message:

Error activating IDependency
More than one matching bindings are available.

You have to provide exact criteria to Ninject to find what implementation of IChildDependency, from same assembly, will suits better

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top