如何在Ninject中为泛型接口实现条件注入绑定?
在Ninject中实现基于命令接口的条件验证器注入
核心思路
要实现仅当命令类实现对应接口时才注入特定验证器,需利用Ninject的条件绑定逻辑,通过检查命令类型是否匹配目标标记接口,动态选择注入对应的验证器实现。
具体实现步骤
1. 基础类型定义(参考结构)
// 命令处理核心接口 public interface ICommandHandler<TCommand> { void Handle(TCommand command); } // 安全验证器接口 public interface ISecurityValidator<TCommand> { void Validate(TCommand command); } // 标记接口:需要资产访问权限的命令 public interface IRequireAccessToAsset { } // 对应验证器:仅处理实现IRequireAccessToAsset的命令 public class RequireAccessToAssetSecurityValidator<TCommand> : ISecurityValidator<TCommand> where TCommand : IRequireAccessToAsset { public void Validate(TCommand command) { // 此处编写资产权限验证逻辑 } } // 示例命令:实现了IRequireAccessToAsset接口 public class FindAssetById : IRequireAccessToAsset { }
2. 配置Ninject条件绑定
通过When方法添加类型检查逻辑,让验证器仅在命令类型匹配时被注入:
// 绑定资产权限验证器:仅当命令实现IRequireAccessToAsset时生效 kernel.Bind(typeof(ISecurityValidator<>)) .To(typeof(RequireAccessToAssetSecurityValidator<>)) .When(request => // 检查当前泛型参数(命令类型)是否实现了目标接口 typeof(IRequireAccessToAsset).IsAssignableFrom(request.GenericArguments[0])); // 绑定命令处理装饰器,用于包裹原始处理逻辑并执行验证 kernel.Bind(typeof(ICommandHandler<>)) .ToDecorator(typeof(SecurityValidationCommandHandlerDecorator<>));
3. 验证装饰器实现
装饰器接收所有匹配当前命令的验证器集合,Ninject会自动筛选符合条件的实例:
public class SecurityValidationCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand> { private readonly ICommandHandler<TCommand> _innerHandler; private readonly IEnumerable<ISecurityValidator<TCommand>> _validators; // Ninject自动注入所有适配当前命令的验证器 public SecurityValidationCommandHandlerDecorator( ICommandHandler<TCommand> innerHandler, IEnumerable<ISecurityValidator<TCommand>> validators) { _innerHandler = innerHandler; _validators = validators; } public void Handle(TCommand command) { // 执行所有匹配的验证逻辑 foreach (var validator in _validators) { validator.Validate(command); } // 执行原始命令处理逻辑 _innerHandler.Handle(command); } }
4. 扩展多验证器场景
如果有其他标记接口(比如IRequireAdminRights),只需重复绑定逻辑即可:
// 绑定管理员权限验证器 kernel.Bind(typeof(ISecurityValidator<>)) .To(typeof(RequireAdminRightsSecurityValidator<>)) .When(request => typeof(IRequireAdminRights).IsAssignableFrom(request.GenericArguments[0]));
关键说明
request.GenericArguments[0]获取的是当前泛型服务(如ISecurityValidator<FindAssetById>)的命令类型参数,通过IsAssignableFrom判断是否匹配标记接口。- Ninject会自动为每个命令类型筛选出所有符合条件的验证器,注入到装饰器的集合参数中。
- 该逻辑与Simple Injector的条件注册逻辑对齐,实现了基于命令接口的精准验证器注入。
内容的提问来源于stack exchange,提问作者Stevenfowler16
相关产品推荐
相关产品推荐

