You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 18:28:01