0

I have a asp.net core web api project with Mediatr 3.0.1 and structureMap.Microsoft.DependencyInjection 1.4.0.

I would like to use the pre and post-processing behavior. The IPipelineBehavior works as expected but thoese 2 don't:

public class PostProcessingBehavior<TRequest, TResponse> : IRequestPostProcessor<TRequest, TResponse>
{
    public Task Process(TRequest request, TResponse response)
    {
        LogTo.Info("Post processing: All Done");
        return Task.FromResult(0);
    }
}

public class PreProcessingBehavior<TRequest>: IRequestPreProcessor<TRequest>
{
    public Task Process(TRequest request)
    {
        // add validators here
        LogTo.Info("Pipline preprocessing happens");

        return Task.FromResult(0);
    }
}

Container registration:

private IServiceProvider ConfigureIoC(IServiceCollection services)
{
    var container = new Container();
    container.Configure(cfg =>
    {
        cfg.Scan(scanner =>
        {
            scanner.AssemblyContainingType(typeof(Startup));
            scanner.AssemblyContainingType(typeof(CustomerGetHandler));
            scanner.ConnectImplementationsToTypesClosing(typeof(IRequestHandler<>)); // Handlers with no response
            scanner.ConnectImplementationsToTypesClosing(typeof(IRequestHandler<,>)); // Handlers with a response
            scanner.ConnectImplementationsToTypesClosing(typeof(IAsyncRequestHandler<>)); // Async handlers with no response
            scanner.ConnectImplementationsToTypesClosing(typeof(IAsyncRequestHandler<,>)); // Async Handlers with a response
            scanner.ConnectImplementationsToTypesClosing(typeof(INotificationHandler<>));
            scanner.ConnectImplementationsToTypesClosing(typeof(IAsyncNotificationHandler<>));
            scanner.WithDefaultConventions();
        });

        cfg.For(typeof(IPipelineBehavior<,>)).Add(typeof(PreProcessingBehavior<>));
        cfg.For(typeof(IPipelineBehavior<,>)).Add(typeof(LoggingBehavior<,>));
        cfg.For(typeof(IPipelineBehavior<,>)).Add(typeof(PostProcessingBehavior<,>));

        cfg.For<SingleInstanceFactory>().Use<SingleInstanceFactory>(ctx => t => ctx.GetInstance(t)).ContainerScoped();
        cfg.For<MultiInstanceFactory>().Use<MultiInstanceFactory>(ctx => t => ctx.GetAllInstances(t)).ContainerScoped();
        cfg.For<IMediator>().Use<Mediator>();

        cfg.Populate(services);
    });

    return container.GetInstance<IServiceProvider>();
}

The error says:
ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: instance 'PostProcessingBehavior' with ReturnType PostProcessingBehavior cannot be cast to IPipelineBehavior

this is from the example: https://github.com/jbogard/MediatR/blob/master/samples/MediatR.Examples.StructureMap/Program.cs

Andre
  • 662
  • 1
  • 8
  • 19

1 Answers1

3

Looking at the example you have linked to you seem to have confused the interfaces.

You have implemented IRequestPostProcessor & IRequestPreProcessor not an IPipelineBehavior.

So you should be registering to the interfaces you are implementing:

cfg.For(typeof(IRequestPreProcessor<>)).Add(typeof(PreProcessingBehavior<>));
cfg.For(typeof(IRequestPostProcessor<,>)).Add(typeof(PostProcessingBehavior<,>));

From reading the documentation, you may also need to register the following

cfg.For(typeof(IPipelineBehavior<,>)).Add(typeof(RequestPreProcessorBehavior<,>));
cfg.For(typeof(IPipelineBehavior<,>)).Add(typeof(RequestPostProcessorBehavior<,>));
Scrobi
  • 1,215
  • 10
  • 13
  • ok I was understanding something totally wrong here. it makes sense now. thanks. I only added your first code snipped, but then nothing happens in the pre and post processors. and the sentence with "register Pre and Post Processors Behavior as IPiplelineBehavior" is not how I was understanding it – Andre Oct 03 '17 at 07:54