i have the following classes
public class GetTestByIdQuery : ICqrsQuery<JustTestDto>
{
public Guid JustTestId { get; set; }
public GetTestByIdQuery(Guid justTestId)
{
JustTestId = justTestId;
}
}
and
public class ListTestsQuery : ICqrsQuery<List<JustTestDto>>
{
}
how can i register them dynamically at the run time using reflection by getting all the classes that implements the interfaces ICqrsQuery and ICqrsQuery<T> ?
i already wrote the following code
public static IServiceCollection AddCqrsQueries(this IServiceCollection services)
{
var assembly = Assembly.GetExecutingAssembly();
var queries = assembly.GetTypes()
.Where(t => t.IsClass && !t.IsAbstract &&
t.GetInterfaces().Any(i => i.IsGenericType &&
i.GetGenericTypeDefinition() == typeof(ICqrsQuery<>)));
foreach (var query in queries)
{
var interfaces = query.GetInterfaces();
foreach (var @interface in interfaces)
{
if (@interface.IsGenericType
&& @interface.GetGenericTypeDefinition() == typeof(ICqrsQuery<>))
{
var constructor = query.GetConstructors().FirstOrDefault();
var constParameters = constructor?.GetParameters() ?? null;
var parameterValues =
constParameters != null ? new object[constParameters.Length] : null;
if (parameterValues?.Length > 0 && parameterValues != null)
{
for (int i = 0; i < constParameters.Length; i++)
{
parameterValues[i] = services.BuildServiceProvider()
.GetService(constParameters[i].ParameterType);
}
services.AddTransient(serviceProvider =>
{
var instance = Activator.CreateInstance(query, parameterValues);
return instance;
});
}
else
{
///no parameters
services.AddTransient(query);
}
}
}
}
return services;
}
it works fine with the classes that has no parameters such as ListTestsQuery but for classes with constructor parameters it doesn't such as GetTestByIdQuery
i have notice that the problem is with var instance = Activator.CreateInstance(query, parameterValues); since its return type is object? although at run time its evaluated to GetTestByIdQuery, if i do explicit casting to type GetTestByIdQuery it works otherwise it doesn't
How can I solve this problem?