I'm creating a Asp.Net Web Api, using clean architecture, CQRS, MediatR and FluentValidation. Recently, MediatR was updated to version 12. I'm having troubles doing the migration (from v11 to v12).
Everything works fine using MediatR v11. But while using v12, the *RequestHandlers *are not automatically detected at run-time.
The exception:
No service for type 'MediatR.IRequestHandler`2[Application.UseCases.Weather.Queries.GetWeatherQuery,CSharpFunctionalExtensions.Result`1[System.Collections.Generic.List`1[Application.UseCases.Weather.Queries.GetWeatherResponse]]]' has been registered.
I created a small repository, using MediatR v11 and v12. Can you help me?
I'm using clean architecture, with the usual layers:
Api project:
<ItemGroup>
<PackageReference Include="FluentValidation" Version="11.5.1" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.5.1" />
<PackageReference Include="MediatR" Version="12.0.1" />
<PackageReference Include="MediatR.Extensions.FluentValidation.AspNetCore" Version="4.0.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
Application project:
<ItemGroup>
<PackageReference Include="CSharpFunctionalExtensions" Version="2.38.1" />
<PackageReference Include="FluentValidation" Version="11.5.1" />
<PackageReference Include="MediatR" Version="12.0.1" />
</ItemGroup>
Api project:
<ItemGroup>
<PackageReference Include="FluentValidation" Version="11.5.1" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.5.1" />
<PackageReference Include="MediatR" Version="11.1.0" />
<PackageReference Include="MediatR.Extensions.FluentValidation.AspNetCore" Version="4.0.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.1.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
Application project:
<ItemGroup>
<PackageReference Include="CSharpFunctionalExtensions" Version="2.38.1" />
<PackageReference Include="FluentValidation" Version="11.5.1" />
<PackageReference Include="MediatR" Version="11.1.0" />
</ItemGroup>
I'm using the sample code for WeatherForecastController
.
I follow the migration guide
That GetWeatherQuery
and its corresponding GetWeatherQueryHandler
are in your Application
assembly.
In your MediatR
v11 version you register that handler in a single call passing in all loaded assemblies, which includes that Application
assembly.
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
services.AddMediatR(assemblies);
In your MediatR
v12 version based code you only register the handlers present in the Api
assembly.
services.AddMediatR(cfg => cfg.RegisterServicesFromAssembly(typeof(Program).Assembly));
To also register the ones in the Application
assembly in a similar way you need to call RegisterServicesFromAssemblies
passing in the same set of assemblies.
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
services.AddMediatR(cfg => cfg.RegisterServicesFromAssemblies(assemblies));
Alternatively, you can be more explicit and only call RegisterServicesFromAssembly
on the 2 concerning assemblies containing MediatR
handlers and so.
This has the benefit of less assembly scanning, since above AppDomain.CurrentDomain.GetAssemblies()
call returns quite some assemblies.
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(typeof(Program).Assembly);
cfg.RegisterServicesFromAssembly(typeof(GetWeatherQuery).Assembly);
});