Search code examples
mediatr

Trying to use IPipelineBehavior with ASP.NET Core - get System.InvalidCastException


I'm using Mediatr 3's new features for Pipeline Behaviors. Problem is, when I wire them into Mediatr, exceptions (System.InvalidCastException) get thrown for every .Send() call. Handlers get called fine, but when its time for the pipeline behaviors to get called, it fails.

Here's my setup:

    services.AddScoped<SingleInstanceFactory>(p => t => p.GetRequiredService(t));
    services.AddScoped<MultiInstanceFactory>(p => t => GetRequiredServices(p,t));
    services.AddScoped(typeof( IPipelineBehavior<, >), typeof(AddSessionBehavior<, >));
    services.AddMediatR();

And my Behavior:

public class AddSessionBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    {
        IHttpContextAccessor Accessor;
        public AddSessionBehavior(IHttpContextAccessor anAccessor)
        {
            this.Accessor = anAccessor;
        }
        public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next)
        {

            var response = await next();
            return response;

        }
    }

When I send my first message through mediator, I get:

System.InvalidCastException occurred
  HResult=0x80004002
  Message=Object cannot be stored in an array of this type.
  Source=<Cannot evaluate the exception source>
  StackTrace:
   at System.Array.InternalSetValue(Void* target, Object value)
   at System.Array.SetValue(Object value, Int32[] indices)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitClosedIEnumerable(ClosedIEnumerableCallSite closedIEnumerableCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at MediatR.ServiceCollectionExtensions.GetRequiredServices(IServiceProvider provider, Type serviceType)
   at MediatR.Internal.RequestHandlerImpl`2.GetPipeline(TRequest request, RequestHandlerDelegate`1 invokeHandler, MultiInstanceFactory factory)
   at MediatR.Internal.RequestHandlerImpl`2.Handle(IRequest`1 request, CancellationToken cancellationToken, SingleInstanceFactory singleFactory, MultiInstanceFactory multiFactory)
   at MediatR.Mediator.Send[TResponse](IRequest`1 request, CancellationToken cancellationToken)
   at Merlin.Web.Controllers.CourseController.Add(CourseAddVM model) 

If I comment out the wiring for my behavior, my handlers get called fine. And the rest of the application seems to work.

What have I done wrong?


Solution

  • I figured it out.

    Turns out that somewhere along the way an internal class with the same name as my behavior was created in a different namespace in my application. Probably the result of a "Generate Class definition".

    Removing the generated class cleared up the issue.