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

MediatR泛型通知处理器多次调用求助(Autofac协变注册相关)

Why is my generic MediatR notification handler called multiple times with Autofac?

Let me break down what's happening here and why you're seeing that triple invocation:

The Problem Recap

You set up a generic MediatR notification system where:

  • You publish a CustomNotification that implements ICustomNotification and inherits from CustomNotificationBase (which also implements ICustomNotification)
  • Your handler is CustomNotificationHandler<TNotification> with a constraint where TNotification : ICustomNotification
  • Instead of being called once, the handler runs three times—once for each of CustomNotification, CustomNotificationBase, and ICustomNotification, all using the same notification instance

This stops happening when you remove Autofac's ContravariantRegistrationSource from your registration, or switch to StructureMap. You added that registration source because you saw it in MediatR docs/examples, but didn't fully understand why it was needed.

Why This Is Happening

1. What ContravariantRegistrationSource Does

Autofac's ContravariantRegistrationSource enables contravariant type resolution. In short, it lets Autofac match a service like INotificationHandler<BaseType> to a registered implementation of INotificationHandler<DerivedType> (since contravariance allows substituting a derived type for a base type in input positions).

For your open generic handler (CustomNotificationHandler<T>), this registration source goes a step further: it generates closed-type registrations for every type that fits your ICustomNotification constraint—including the concrete class, its base class, and the interface itself.

2. How MediatR Finds Notification Handlers

When MediatR publishes a notification, it scans for all handlers that can handle:

  • The exact notification type you published
  • All base types of that notification
  • All interfaces the notification implements

With ContravariantRegistrationSource enabled, Autofac has created three distinct closed-type handlers (CustomNotificationHandler<CustomNotification>, CustomNotificationHandler<CustomNotificationBase>, CustomNotificationHandler<ICustomNotification>) that all match MediatR's search criteria. So MediatR calls all three.

3. Why Removing the Registration Source Fixes It

Without ContravariantRegistrationSource, Autofac only generates the most specific closed-type handler for your open generic registration: CustomNotificationHandler<CustomNotification>. MediatR only finds this one handler, so it's called once as expected.

4. Why StructureMap Doesn't Have This Issue

StructureMap's generic resolution logic works differently—it doesn't automatically generate closed-type registrations for every matching base type/interface. It only resolves the most specific type that fits the request, so you don't get multiple handler instances being picked up.

Is This a Bug or Usage Issue?

This is a usage mismatch, not an Autofac bug:

  • The MediatR docs mention ContravariantRegistrationSource for scenarios where you need to handle notifications at a more abstract level (e.g., a single handler for all INotification implementations).
  • Your generic handler already uses a type constraint to target ICustomNotification implementations. Adding the contravariant registration source causes Autofac to over-generate handler instances, which MediatR then picks up and invokes.

Fixes You Can Use

To get the single-invocation behavior you want:

  • Remove ContravariantRegistrationSource: Unless you explicitly need contravariant support (like handling all notifications with a base handler), this is the simplest fix.
  • Explicitly constrain handler registration: If you need to keep the registration source, you can adjust your Autofac registration to only target concrete notification types (though this loses some of the generic flexibility you wanted).

内容的提问来源于stack exchange,提问作者smartypants

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:23:58