Validation Rule Contract:
public interface IValidationRule
{
bool IsValid();
}
Concrete Validation Rule:
public class MyClass : IValidationRule
{
public bool IsValid()
{
return true;
}
}
Composite:
public class ValidationRuleComposite : IValidationRule
{
private readonly IEnumerable<IValidationRule> _validationRules;
public ValidationRuleComposite(IEnumerable<IValidationRule> validationRules)
{
_validationRules = validationRules;
}
public bool IsValid()
{
return _validationRules.All(x => x.IsValid());
}
}
When I ask the containter for IValidationRule
I want to get ValidationRuleComposite
. If I ask the container for a list of IValidationRule
I want to get all implementations of IValidationRule
except of the ValidationRuleComposite
.
How can I achieve this with Ninject?
With the help of Soldarnal I came to the following solution:
public static class KernelExtensions
{
public static void BindComposite<TComposite, TCompositeElement>(this StandardKernel container) where TComposite : TCompositeElement
{
container.Bind(x => x.FromAssemblyContaining(typeof(TComposite))
.SelectAllClasses()
.InheritedFrom<TCompositeElement>()
.Excluding<TComposite>()
.BindAllInterfaces()
.Configure(c => c.WhenInjectedInto<TComposite>()));
container.Bind<TCompositeElement>().To<TComposite>()
.When(IsNotCompositeTarget<TComposite>);
}
private static bool IsNotCompositeTarget<TComposite>(IRequest x)
{
if (x.Target == null)
return true;
return x.Target.Member.ReflectedType != typeof(TComposite);
}
}
Usage:
var container = new StandardKernel();
container.BindComposite<ValidationRuleComposite, IValidationRule>();