I have a generic class Result
that looks like this
public class Result<T>
{
public List<Error> Errors { get; set; } = new List<Error>();
public T ResultObject { get; set; }
public Result(List<Error> errors)
{
Errors = errors;
Success = false;
}
}
I try to create an instance like this:
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate<TResponse> next)
{
var context = new ValidationContext<TRequest>(request);
var failures = _validators
.Select(v => v.Validate(context))
.SelectMany(result => result.Errors)
.Where(f => f != null)
.ToList();
if (failures.Count != 0)
{
var responseType = typeof(TResponse);
// This is the important line
return Task.FromResult(Activator.CreateInstance(responseType, new object[] { failures.Select(x => new Error(x.ErrorMessage)).ToList() }) as TResponse);
}
return next();
}
TResponse
is of type Result<GetUserFlow>
. GetUserFlow
is a dto but not important in this case. When I run my code I get the following error:
System.MissingMethodException: Constructor on type 'Heimdall.Application.Result`1[[Heimdall.Application.Dtos.GetUserFlow, Heimdall.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found.
I guess the problem is that when passing a list as parameter it isn't seen as one parameter but as many. Each created Error is one parameter. I couldn't find anything about this topic.
You can invoke the correct constructor with:
constructorInfo.Invoke(new object[] { failures.Select(x => new Error(x.ErrorMessage)).ToList() }) as TResponse
To get the constructor, use somthing like this:
responseType.GetConstructors()[0]
// if you have multiple constructors, ensure the correct one with:
responseType.GetConstructor(new Type[]{ typeof(List<Error>) })
By the way, you may find the factory pattern much easier.
Pass through to the Handle function a factory delegate Func<List<Errors>, TResponse>
and use that delegate to call the constructor.
public Task<TResponse> Handle(TRequest request, CancellationToken cancellationToken,
RequestHandlerDelegate<TResponse> next, Func<List<Errors>, TResponse> responseCreator)
{
....
return Task.FromResult(responseCreator(
failures.Select(x => new Error(x.ErrorMessage)).ToList()
));
....
}
You call it like this:
var result = Handle(...., errors => new Result<GetUserFlow>(errors));
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.