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

SimpleInjector注册两个IEnumerable<Type>实例报错求助

SimpleInjector中IMiddleware集合依赖注册问题解决

问题概述

使用SimpleInjector时触发配置无效错误:创建IMiddleware实例失败,LogContextMiddleware构造函数中controllerTypeExclusionList(类型IEnumerable<Type>)参数未注册。错误提示需通过Container.Collection.Register或Append注册集合,空集合也需注册。

现有注册逻辑中,两个中间件(LogContextMiddleware、AuthorizationMiddleware<AppToken>)需要不同的排除类型列表,无法共用同一IEnumerable<Type>实例。

解决方案

方案1:创建专属包装类区分依赖

通过定义不同的包装类,将各自的排除列表封装,避免类型依赖冲突:

  1. 定义包装类:
// 日志中间件专属排除列表包装
public class LogControllerExclusions
{
    public IEnumerable<Type> Types { get; }

    public LogControllerExclusions(IEnumerable<Type> types) => Types = types;
}

// 授权中间件专属排除列表包装
public class AuthorizationControllerExclusions
{
    public IEnumerable<Type> Types { get; }

    public AuthorizationControllerExclusions(IEnumerable<Type> types) => Types = types;
}
  1. 修改中间件构造函数,依赖对应包装类:
public class LogContextMiddleware : IMiddleware
{
    private readonly IEnumerable<Type> controllerTypeExclusionList;
    private readonly ILogger logger;

    public LogContextMiddleware(LogControllerExclusions exclusions, ILogger logger)
    {
        controllerTypeExclusionList = exclusions.Types;
        this.logger = logger;
    }

    // 中间件InvokeAsync逻辑...
}

// 同理修改AuthorizationMiddleware<AppToken>构造函数,依赖AuthorizationControllerExclusions
  1. 注册包装类与中间件:
// 注册日志排除列表实例
container.RegisterInstance(new LogControllerExclusions(
    new List<Type> { typeof(StatusController) }));

// 注册授权排除列表实例
container.RegisterInstance(new AuthorizationControllerExclusions(
    new List<Type> { typeof(StatusController), typeof(PruebaSinAuthController) }));

// 注册中间件
container.Register<LogContextMiddleware>(Lifestyle.Transient);
container.Register<AuthorizationMiddleware<AppToken>>(Lifestyle.Transient);

方案2:使用条件注册(命名依赖)

借助SimpleInjector的RegisterConditional,根据目标消费类型注入对应集合:

// 注册两个不同的排除列表实例(带命名标识)
var logExclusions = new List<Type> { typeof(StatusController) };
container.RegisterInstance<IEnumerable<Type>>(logExclusions, "LogExclusions");

var authExclusions = new List<Type> { typeof(StatusController), typeof(PruebaSinAuthController) };
container.RegisterInstance<IEnumerable<Type>>(authExclusions, "AuthExclusions");

// 为LogContextMiddleware指定注入日志排除列表
container.RegisterConditional(
    typeof(IEnumerable<Type>),
    ctx => ctx.GetInstance<IEnumerable<Type>>("LogExclusions"),
    c => c.Consumer.ImplementationType == typeof(LogContextMiddleware));

// 为AuthorizationMiddleware<AppToken>指定注入授权排除列表
container.RegisterConditional(
    typeof(IEnumerable<Type>),
    ctx => ctx.GetInstance<IEnumerable<Type>>("AuthExclusions"),
    c => c.Consumer.ImplementationType == typeof(AuthorizationMiddleware<AppToken>));

// 注册中间件
container.Register<LogContextMiddleware>(Lifestyle.Transient);
container.Register<AuthorizationMiddleware<AppToken>>(Lifestyle.Transient);

方案3:让SimpleInjector接管中间件激活(推荐)

ASP.NET Core默认使用自身DI激活IMiddleware,替换为SimpleInjector的中间件工厂后,可确保依赖由SimpleInjector解析:

  1. 注册SimpleInjector中间件工厂:
container.Register<ISimpleInjectorMiddlewareFactory, SimpleInjectorMiddlewareFactory>(Lifestyle.Singleton);
  1. 在Program.cs中配置使用该工厂:
app.UseSimpleInjector(container);
app.UseMiddleware<SimpleInjectorMiddlewareFactory>();
  1. 用条件注册为每个中间件绑定对应排除列表:
var logExclusions = new List<Type> { typeof(StatusController) };
container.RegisterConditional(
    typeof(IEnumerable<Type>),
    _ => InstanceProducer.ForInstance(logExclusions),
    c => c.Consumer.ImplementationType == typeof(LogContextMiddleware));

var authExclusions = new List<Type> { typeof(StatusController), typeof(PruebaSinAuthController) };
container.RegisterConditional(
    typeof(IEnumerable<Type>),
    _ => InstanceProducer.ForInstance(authExclusions),
    c => c.Consumer.ImplementationType == typeof(AuthorizationMiddleware<AppToken>));

// 注册中间件
container.Register<LogContextMiddleware>(Lifestyle.Transient);
container.Register<AuthorizationMiddleware<AppToken>>(Lifestyle.Transient);

内容的提问来源于stack exchange,提问作者Iñaki P. B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:07:50