20

I'm using ASP.Net Core 2.2 and MediatR framework/library for query objects. When I run the program i face to this exception:

InvalidOperationException: Handler was not found for request of type MediatR.IRequestHandler2[Store.Core.Queries.GetProductTypesQuery,System.Collections.Generic.IEnumerable1[Store.Core.DomainModels.ProductType]]. Register your handlers with the container.

I added these packaged to my Store project (main project)

1- MediatR 7.0.0

2- MediatR.Extensions.Microsoft.DependencyInjection

This is my Startup.cs

services.AddMediatR(typeof(Startup));

So this is my Query (located in a project called "Store.Core")

namespace Store.Core.Queries.Products
{
   public class GetProductTypesQuery : IRequest<IEnumerable<ProductType>> { }
}

This is my QueryHandler (located in another project called "Store.Data")

namespace Data.Queries.Products
{
    public class GetProductTypesQueryHandler : IRequestHandler<GetProductTypesQuery, IEnumerable<ProductType>>
    {
        private ApplicationDbContext _context;
        public GetProductTypesQueryHandler(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<IEnumerable<ProductType>> Handle(GetProductTypesQuery request, CancellationToken cancellationToken)
        {
            return await _context.ProductType.OrderBy(p => p.ProductTypeID).ToListAsync();
        }

    }
}

This is the Controller I used the MediatR

namespace Store.Controllers
{
    public class HomeController : Controller
    {
        private readonly IMapper _mapper;
        private readonly IMediator _mediator;
        public HomeController(IMapper mapper, IMediator mediator)
        {
            _mapper = mapper;
            _mediator = mediator;   
        }


        public IActionResult Home() => View();

        [HttpGet]
        public async Task<IActionResult> Dishes(GetProductTypesQuery query) {
            var productTypes = await _mediator.Send(query);
            var productTypesViewModel = _mapper.Map<IEnumerable<ProductTypeVM>>(productTypes);
            return View(productTypesViewModel);
        }
}
}

my ProductType model (I Think it's not necessary but i added it in order to provide full info)

namespace Store.Core.DomainModels
{
    public class ProductType
    {
       public int ProductID { get; set; }
       public string ProductName { get; set; }
    }
}

The only part which is fishy for me is StartUp.cs (because I have queries and queries handlers in diffrent projects) but I don't know what i'm missing.

Arian Shahalami
  • 1,369
  • 2
  • 13
  • 25

6 Answers6

37

As I guessed, the problem was the Startup.cs where u add the MediatR service. Since my Handlers were in separate assembly so we should mention that assembly name. I changed this in Startup.cs

public void ConfigureServices(IServiceCollection services) {
    services.AddMediatR(typeof(Startup));
}

To this:

public void ConfigureServices(IServiceCollection services){
    var assembly = AppDomain.CurrentDomain.Load("Data");
    services.AddMediatR(assembly);
}

Here "Data" is the name of my assembly where all Handlers are stored there.

Arian Shahalami
  • 1,369
  • 2
  • 13
  • 25
  • 1
    In one of my projects I user like this `services.AddMediatR();` and works perfectly. Another project with exact configuration and NuGet packages I had to use as you show above. Thanks, it solved my problem but why would my other project works **without** the assembly input. All of them have the same namespaces in both projects. – E-A Jul 11 '20 at 08:54
3

I needed to use:

services.AddMediatR(typeof(DeletePeopleCommand).GetTypeInfo().Assembly);
double-beep
  • 5,031
  • 17
  • 33
  • 41
Felipe Augusto
  • 1,341
  • 1
  • 16
  • 18
1

You can use this

public void ConfigureServices(IServiceCollection services){
        services.AddMediatR(AppDomain.CurrentDomain.GetAssemblies());
    }

Here GetAssemblies() will load all handler classes.

  • I try this but it will not load handlers. instead i get assembly by name and it works : services.AddMediatR(AppDomain.CurrentDomain.Load("Data")) – ehsan Jul 28 '21 at 07:21
0

I had this error.

Like a fool I had forgotten to make my handler implement IRequestHandler<TRequest, TResponse>, without which the container isn't looking for the handler.

Neil Thompson
  • 6,356
  • 2
  • 30
  • 53
0

Make sure your handler is public.

Harry
  • 1,686
  • 2
  • 15
  • 21
0

It also can be a problem if our RequestHandler in other csproj.

We have to find all these assemblies in startup, and register a proper way.

totesz09
  • 164
  • 1
  • 11