-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error: Arity of open generic service type INotificationHandler<> does not equal arity of open generic implementation type #674
Comments
Hello, I have exactly the same error in .Net 6 but not directly with MediatR. I'm trying to register a generic repository like this: serviceDescriptors.AddTransient(typeof(IRepository<>), typeof(EntityRepository<,>)); and tada : Arity of open generic service type 'Bot.Core.Interfaces.Persistence.IRepository`1[TEntity]' does not equal arity of open generic implementation type 'Bot.Infrastructure.Persistence.Repositories.EntityRepository`2[TEntity,TId]'. (Parameter 'descriptors') but if I register them one by one, it works : serviceDescriptors.AddTransient<IRepository<User>, EntityRepository<User, int>>(); related issue : dotnet/runtime#61407 |
@Adwelean Thanks! Your link is super helpful - looks the root of the issue. I know this isn't a MediatR specific issue but it seems like this recent .Net update is going to cause some problems. The generic notification handler is a pattern I've used for a long time and it's always worked well for me until now. Am I the only one? I don't mind registering my handlers manually; that's what I've always had to do for these. But now AddMediatR() is broken and I'd rather not implement my own version. I have a few ideas to get around this but they're not pretty, and I thought I'd check here first to see if there's a known solution. |
jbogard/MediatR.Extensions.Microsoft.DependencyInjection#79 likewise shows an arity error, although not quite the same one; that one was thrown during service instantiation rather than registration. If I understand correctly, Microsoft.Extensions.DependencyInjection has never been able to create instances of a service that was registered as an open generic type with a mismatching arity. MediatR.Extensions.Microsoft.DependencyInjection should not attempt to make such registrations. |
Hello @markmillercc ! I'm using .NET 6 and the MediatoR v12.1.1 but not the MediatR.Extensions.Microsoft.DependencyInjection. I tried to do exactly what @Adwelean did, which is the following service registration : Any help is welcome ;) |
Hi @AxSamyn I don't think your issue is related to MediatR. It's been a little while since I've looked at this, but if I recall the issue is that your registration is not valid. When the container attempts to resolve Previously, .NET would allow this registration but would error when you try to resolve. The .NET 6 update just moved the error to the point of registration. This would make more sense:
So if you were to call I explain a similar scenario in readme for my repo here: https://github.com/markmillercc/MediatRClub Long story short, the "fix" for my original issue was not to allow such registrations, but to prevent MediatR from attempting to apply the registration because it would not be valid. |
Ok thanks for pointing this out ! I'm new to the concept of dependency injection, and while i thought i mastered the basics, I'll go and check the documentation again, cause my initial assumption was that the dependency injection system would find a way to determine this, like some kind of magic... :) More seriously, I wanted to avoid manual declaration of the different types linked to the interface. Anyway, thanks again for the help ! |
You can use Source Generators for register your repository 😎 |
For anyone dealing with registration of request pipeline for void requests, I have this solution which worked for me public class VoidRequestValidationBehavior<TRequest, TResponse>(IEnumerable<IValidator<TRequest>> validators) : IPipelineBehavior<TRequest, Unit>
where TRequest : IRequest
{
public async Task<Unit> Handle(TRequest request, RequestHandlerDelegate<Unit> next, CancellationToken cancellationToken)
{
// Validate request
var context = new ValidationContext<TRequest>(request);
var failures = (await Task.WhenAll(validators
.Select(v => v.ValidateAsync(context, cancellationToken))))
.SelectMany(result => result.Errors)
.Where(error => error != null)
.ToList();
if (failures.Any())
throw new AppValidationException(failures);
return await next();
}
} registration
Yes |
This solution works. |
Using AspNet Core DI and MediatR version 9.0, I am running into this issue after upgrading Microsoft.Extensions.Hosting from version 5 to 6.
Here's a simple reproduction, with dependencies:
This was working fine with Microsoft.Extensions.Hosting v 5.0.0. After upgrading to 6.0.0, the same code fails with error:
Arity of open generic service type 'MediatR.INotificationHandler1[TNotification]' does not equal arity of open generic implementation type 'Ventana.Communication.GenericEventHandler2[TEvent,TCommand]'. (Parameter 'descriptors')
My guess is that during
AddMediatR()
, it's attempting to do something like this:The error makes sense, although I don't understand why it was working before.
Any suggestions?
Can I tell MediatR to ignore certain types when auto-registering handlers? Or skip any auto-registration and just register all of my handlers explicitly (ugh)?
Neither of those are ideal - before upgrading, everything was working smooth and I had the benefit of using MediatR's auto registration for standard handlers, while I could also explicitly register my generic handlers.
Any help is appreciated, thanks!
The text was updated successfully, but these errors were encountered: