Generic Requests / Handlers #902
zachpainter77
started this conversation in
Ideas
Replies: 1 comment
-
Here is the static method I am proposing be added to the Anyways any feedback would be appreciated. public static void RegisterGenericHandlers(IServiceCollection services, MediatRServiceConfiguration configuration)
{
var assembliesToScan = configuration.AssembliesToRegister.Distinct().ToArray();
var allTypes = assembliesToScan
.SelectMany(x => x.GetTypes())
.Where(type => type.IsClass)
.Where(type => !type.IsAbstract);
var genericHandlerTypes = allTypes
.Where(x => x.IsGenericType)
.Where(type => type.GetInterfaces()
.Where(intrface => intrface.IsGenericType)
.Select(intrface => intrface.GetGenericTypeDefinition())
.Any(interfaceType => interfaceType == typeof(IRequestHandler<>) || interfaceType == typeof(IRequestHandler<,>))
);
var genericRequestTypes = allTypes
.Where(x => x.IsGenericType)
.Where(type => type.GetInterfaces()
.Where(intrface => intrface.IsGenericType)
.Select(intrface => intrface.GetGenericTypeDefinition())
.Any(interfaceType => interfaceType == typeof(IRequest<>))
|| type.GetInterfaces().Any(interfaceType => interfaceType == typeof(IRequest))
);
var concreateRequestTypes = new List<Type>();
foreach (var genericRequest in genericRequestTypes)
{
var genericArgument = genericRequest.GetGenericArguments().First();
var constraints = genericArgument.GetGenericParameterConstraints();
var entityTypes = allTypes.Where(entity => constraints.All(constraint => constraint.IsAssignableFrom(entity)));
concreateRequestTypes.AddRange(entityTypes.Select(entity => genericRequest.MakeGenericType(entity)));
}
foreach (var implementationHandlerType in genericHandlerTypes)
{
var genericArgument = implementationHandlerType.GetGenericArguments().First();
var handlerConstraints = genericArgument.GetGenericParameterConstraints();
var serviceHandlerType = implementationHandlerType
.GetInterfaces()
.Select(x => x.GetGenericTypeDefinition())
.Single(x => x == typeof(IRequestHandler<>) || x == typeof(IRequestHandler<,>));
var requestTypeArgument = implementationHandlerType
.GetInterfaces()
.Single(x => x.GetGenericTypeDefinition() == typeof(IRequestHandler<>) || x.GetGenericTypeDefinition() == typeof(IRequestHandler<,>))
.GenericTypeArguments.First();
var requestTypes = concreateRequestTypes.Where(tRequest => tRequest.Name == requestTypeArgument.Name);
foreach (var requestType in requestTypes)
{
var entity = requestType.GetGenericArguments().First();
var responseType = requestType
.GetInterfaces()
.Where(x => x.IsGenericType)
.Where(x => x.GetGenericTypeDefinition() == typeof(IRequest<>))
.SelectMany(x => x.GetGenericArguments())
.FirstOrDefault();
if (responseType != null)
{
services.AddTransient(serviceHandlerType.MakeGenericType(requestType, responseType), implementationHandlerType.MakeGenericType(entity));
}
else
{
services.AddTransient(serviceHandlerType.MakeGenericType(requestType), implementationHandlerType.MakeGenericType(entity));
}
}
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hello, I have a need to register this kind of implementation.
I previously used AutoFac to do this but for some reason trying to use AutoFac with Azure AD B2C OpenIdConnect isn't working.
So I came up with a solution that uses assembly scanning / reflection to register the concrete implementations.
My thought was to add a boolean property to the
MediatRServiceConfiguration
class.Then I added a static method in the
ServiceRegistrar
class.And finally added logic to call the method inside of the
AddMediatR
service collection extension method if the user was to set the configuration property to true.Is this a feature that you are wanting to support? It seems like it has been quite the hot topic for a while now. I was thinking that if you wanted to support this you would have done it by now. But if not, Then I do have a a solution that is working for me.. Should I create a PR and let it be reviewed?
Here is what my request and handlers look like for the most part.
Cheers! and thank you for the time to review this idea.
Beta Was this translation helpful? Give feedback.
All reactions