N引入验证器链;实现相同接口的聚合

本文关键字:接口 实现 验证 | 更新日期: 2023-09-27 18:26:35

我有这个:

interface IValidator
{
  bool InputOK(Text);
}
class ValidatorChain : IValidator
{
  ValidatorChain(IEnumerable<IValidator> other_validators_in_order) {...}
  bool InputOK(Text) { return other_validators_in_order.All(v=>v.InputOK(Text)); }
}
ConcreteValidator1 : IValidator {...}
ConcreteValidator2 : IValidator {...}
ConcreteValidator3 : IValidator {...}

我想用ninject绑定这个,足够简单;

Bind<IValidator>.To<ConcreteValidator1>();
Bind<IValidator>.To<ConcreteValidator2>();
Bind<IValidator>.To<ConcreteValidator3>();

现在,问题是我想在其他地方使用这个链,只需要在那里注入。如果我尝试

Bind<IValidator>.To<ConcreteValidator1>().WhenInjectedExactlyInto(typeof(ValidatorChain));
Bind<IValidator>.To<ConcreteValidator2>().WhenInjectedExactlyInto(typeof(ValidatorChain));
Bind<IValidator>.To<ConcreteValidator3>().WhenInjectedExactlyInto(typeof(ValidatorChain));
Bind<IValidator>.To<ValidatorChain>();

起初它似乎有效,但由于最后一行,我得到了循环依赖关系。我在最后一次绑定时尝试了When,但没有成功。

我该如何解决这个问题?

编辑:另外,我应该添加,我不想向类添加任何属性。

N引入验证器链;实现相同接口的聚合

因此,为了修复循环依赖关系,当目标本身是ValidatorChain时,不应应用最后一个绑定。这就像WhenNotInjectedInto(typeof(ValidatorChain)),它当然不存在,但您可以通过使用When并检查目标类型来获得相同的结果:

Bind<IValidator>().To<ValidatorChain>()
    .When(req => req.Target == null || req.Target.Type != typeof(ValidatorChain));

即,当目标为空(称为kernel.Get<IValidator>()的人)或目标不是ValidatorChain本身时,解析为ValidatorChain

奇怪。。。我玩了一下,发现以下方法有效:

Bind<IValidator>().To<ValidatorChain>()
    .When(req => req.Target == null || req.Target.Type != typeof(IEnumerable<IValidator>));

这当然不是很健壮,但在这种情况下,我可以完全控制使用。看起来目标是"请求的类型",而不是"请求的对象"。