6
votes

le programme ne parvient pas à trouver le gestionnaire pour la requête MediatR ASP.Net Core

J'utilise ASP.Net Core 2.2 et le framework / bibliothèque MediatR pour les objets de requête. Lorsque j'exécute le programme, je suis confronté à cette exception:

InvalidOperationException: le gestionnaire n'a pas été trouvé pour la demande de type MediatR.IRequestHandler 2[Store.Core.Queries.GetProductTypesQuery,System.Collections.Generic.IEnumerable 1 [Store.Core.DomainModels.ProductType]]. Enregistrez vos gestionnaires avec le conteneur.

J'ai ajouté ces packages à mon projet Store (projet principal)

1- MediatR 7.0.0

2- MediatR.Extensions.Microsoft.DependencyInjection

C'est mon Startup.cs

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

Voici donc ma requête (située dans un projet appelé "Store.Core")

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);
        }
}
}

Ceci est mon QueryHandler (situé dans un autre projet appelé "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();
        }

    }
}

C'est le contrôleur que j'ai utilisé le MediatR

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

mon modèle ProductType (je pense que ce n'est pas nécessaire mais je l'ai ajouté afin de fournir des informations complètes)

services.AddMediatR(typeof(Startup));

La seule partie qui est louche pour moi est StartUp.cs (parce que j'ai des requêtes et des gestionnaires de requêtes dans différents projets) mais je ne sais pas ce qui me manque.


0 commentaires

5 Réponses :


17
votes

Comme je l'ai deviné, le problème était le Startup.cs où vous ajoutez le service MediatR. Étant donné que mes gestionnaires étaient dans un assembly séparé, nous devrions donc mentionner ce nom d'assembly. J'ai changé cela dans Startup.cs

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

Pour ça:

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

Ici "Data" est le nom de mon assembly où tous les Handlers y sont stockés.


1 commentaires

Dans l'un de mes projets, j'aime ce services.AddMediatR(); et fonctionne parfaitement. Un autre projet avec une configuration exacte et des packages NuGet que j'ai dû utiliser comme vous l'avez montré ci-dessus. Merci, cela a résolu mon problème, mais pourquoi mon autre projet fonctionnerait-il sans l'entrée d'assemblage. Tous ont les mêmes espaces de noms dans les deux projets.



1
votes

J'avais besoin d'utiliser:

services.AddMediatR(typeof(DeletePeopleCommand).GetTypeInfo().Assembly);


0 commentaires

-1
votes

J'ai eu cette erreur.

Comme un imbécile, j'avais oublié de faire en sorte que mon gestionnaire implémente IRequestHandler<TRequest, TResponse> , sans lequel le conteneur ne recherche pas le gestionnaire.


0 commentaires

0
votes

Assurez-vous que votre gestionnaire est public.


0 commentaires

0
votes

Vous pouvez utiliser ceci

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

Ici, GetAssemblies() chargera toutes les classes de gestionnaire.


0 commentaires