MediatR未在Autofac中注册:请求处理组件注册异常求助
异常详情
Autofac.Core.Registration.ComponentNotRegisteredException
HResult=0x80131500
Message=请求的服务'MediatR.IRequestHandler2[[MyApp.Features.Auth.SignIn.Requests.SignInRequest, MyApp.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[MyApp.Features.Auth.SignIn.Response.SignInResponse, MyApp.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'尚未注册。要避免此异常,请注册提供该服务的组件、使用IsRegistered()检查注册情况,或使用ResolveOptional()解析可选依赖项。 Source=Autofac StackTrace: at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable1 parameters)
at MyApp.Infrastructure.MediatorModules.MediatorModules.<>c__DisplayClass0_0.b__2(Type t) in E:\JJ\MyApp\MyApp.Infrastructure\MediatorModules\MediatorModules.cs:line 23
at MediatR.ServiceFactoryExtensions.GetInstance[T](ServiceFactory factory)
at MediatR.Wrappers.HandlerBase.GetHandler[THandler](ServiceFactory factory)
相关代码
MyMediatorModule类
public class MyMediatorModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<Mediator>() .As<IMediator>() .InstancePerLifetimeScope(); builder.Register<ServiceFactory>(context => { var c = context.Resolve<IComponentContext>(); return t => c.Resolve(t); }); builder.RegisterAssemblyTypes(typeof(MyMediatorModule ).Assembly) .Where(t => t.Namespace.Contains("MyApp.Features")) .AsImplementedInterfaces(); } }
Startup配置
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Host.ConfigureContainer<ContainerBuilder>(builder => { builder.RegisterAssemblyModules(typeof(MyMediatorModule).Assembly); builder.RegisterAssemblyModules(typeof(Program).Assembly); });
SignInRequestHandler类
public class SignInRequestHandler : RequestHandler<SignInRequest, SignInResponse> { public SignInRequestHandler(DataContext dataContext) : base(dataContext) { } public async override Task<SignInResponse> Handle(SignInRequest request, CancellationToken cancellationToken) { ... } }
SignInRequest类
public class SignInRequest : Request<SignInResponse> { public string? Email { get; set; } }
SignInResponse类
public class SignInResponse { public bool IsStatus { get; set; } }
RequestHandler抽象类
public abstract class RequestHandler<T, TResult> : IRequestHandler<T, TResult> where T : IRequest<TResult> { internal readonly DataContext _dataContext; public RequestHandler(DataContext dataContext) { _dataContext = dataContext; } public abstract Task<TResult> Handle(T request, CancellationToken cancellationToken); }
Request抽象类
public abstract class Request<T> : IRequest<T> { }
错误原因分析
- 程序集扫描范围错误:
MyMediatorModule位于MyApp.Infrastructure程序集,但SignInRequestHandler属于MyApp.Application程序集(从异常信息的类型全名可确认),当前注册代码仅扫描了MyMediatorModule所在的程序集,未包含处理器所在的程序集,导致处理器未被注册。 - 命名空间过滤逻辑冗余:即使目标类型符合命名空间规则,扫描范围错误也无法找到目标类型。
解决方法
方法一:扩展程序集扫描范围
修改MyMediatorModule中的注册代码,同时包含处理器所在的程序集:
builder.RegisterAssemblyTypes( typeof(MyMediatorModule).Assembly, typeof(SignInRequestHandler).Assembly) .Where(t => t.Namespace?.Contains("MyApp.Features") == true) .AsImplementedInterfaces();
方法二:在Startup中单独注册目标程序集
若不想修改MyMediatorModule,可在Startup的容器配置中直接注册MyApp.Application程序集的类型:
builder.Host.ConfigureContainer<ContainerBuilder>(builder => { builder.RegisterAssemblyModules(typeof(MyMediatorModule).Assembly); builder.RegisterAssemblyModules(typeof(Program).Assembly); // 新增:注册MyApp.Application中的处理器 builder.RegisterAssemblyTypes(typeof(SignInRequestHandler).Assembly) .Where(t => t.Namespace?.Contains("MyApp.Features") == true) .AsImplementedInterfaces(); });
方法三:使用MediatR官方Autofac扩展包(推荐)
借助官方扩展简化注册逻辑,避免手动扫描出错:
- 安装NuGet包:
Install-Package MediatR.Extensions.Autofac.DependencyInjection - 修改
MyMediatorModule的Load方法:
protected override void Load(ContainerBuilder builder) { builder.RegisterMediatR(typeof(SignInRequestHandler).Assembly); }
该扩展会自动注册所有IRequestHandler、INotificationHandler等MediatR相关类型,无需手动处理扫描逻辑。
内容的提问来源于stack exchange,提问作者Illep

