如何将“复合设计模式”与 Ninject 结合使用

2024-02-09

验证规则合约:

public interface IValidationRule
{
    bool IsValid();
}

具体验证规则:

public class MyClass : IValidationRule
{
    public bool IsValid()
    {
        return true;
    }
}

合成的:

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());
    }
}

当我向容器询问时IValidationRule我想要得到ValidationRuleComposite。如果我向容器询问一个列表IValidationRule我想获得所有的实现IValidationRule除了ValidationRuleComposite.

我如何使用 Ninject 实现这一目标?


首先,您需要为将注入到组合中的 IEnumerable 设置绑定。您可以单独绑定它们:

// Bind all the individual rules for injection into the composite
kernel.Bind<IValidationRule>().To<MyClass>().WhenInjectedInto<ValidationRuleComposite>();
kernel.Bind<IValidationRule>().To<RuleTwo>().WhenInjectedInto<ValidationRuleComposite>();

或者您也可以使用以下命令相当简单地设置 IEnumerable约定绑定扩展 https://github.com/ninject/ninject.extensions.conventions,这样您就不必为每个单独的具体规则添加单独的绑定。只需确保为复合类添加 Exclusion 子句,如下所示:

using Ninject.Extensions.Conventions;

// Bind all the non-composite IValidationRules for injection into ValidationRuleComposite
kernel.Bind(x => x.FromAssemblyContaining(typeof(ValidationRuleComposite))
    .SelectAllClasses()
    .InheritedFrom<IValidationRule>()
    .Excluding<ValidationRuleComposite>()
    .BindAllInterfaces()
    .Configure(c => c.WhenInjectedInto<ValidationRuleComposite>()));

在我的示例中,复合材料和其余混凝土位于同一组件中,但显然,如果它们位于其他位置,您可以改变约定绑定。

最后,我们需要设置绑定,以便在其他地方请求 IValidationRule,Ninject 提供组合。似乎没有一个优雅的方法可以解决这个问题,所以我编写了自己的 When 子句来避免循环注入:

// Now bind the composite to the interface for everywhere except itself
kernel.Bind<IValidationRule>().To<ValidationRuleComposite>()
    .When(x => x.Target == null
          || x.Target.Member.ReflectedType != typeof(ValidationRuleComposite));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将“复合设计模式”与 Ninject 结合使用 的相关文章

随机推荐