I want to set args.ReturnValue
to instance of an object created from TResponse<T>
method called Create
.
[Serializable]
public sealed class LogError : OnMethodBoundaryAspect
{
public override void OnException(MethodExecutionArgs args)
{
// Logging part..
MethodInfo methodInfo = (MethodInfo)args.Method;
// I want to replace line below comment to get TResponse<T> object instead of dynamic if possible
dynamic returnValue = Activator.CreateInstance(methodInfo.ReturnType);
args.ReturnValue = returnValue.Create(CodeMessage.InternalError, MessageType.Error, args.Exception);
args.FlowBehavior = FlowBehavior.Return;
}
}
Method ReturnType
will always be TResponse<T>
, but I don't know how to create instance of TResponse<T>
based on method return type. TResponse<T>
implements method with this signature:
.Create(CodeMessage.InternalError, MessageType.Error, args.Exception);
Create
method is static method that returns TResponse<T>
object with parameters set.
Since I didn't know how to do what I want I used Activator
to create instance of method return type and store it to dynamic
type, but it throws RuntimeBinderException
when I call Create
method.
Since Create(...)
is static, you don't need to create an instance by using the Activator
class. Just get a MethodInfo
from the ReturnType and invoke it with null
as first argument:
public override void OnException(MethodExecutionArgs args)
{
// Logging part..
MethodInfo methodInfo = (MethodInfo)args.Method;
MethodInfo create = methodInfo.ReturnType.GetMethod(
"Create",
new[] { typeof(CodeMessage), typeof(MessageType), typeof(Exception) });
args.ReturnValue = create.Invoke(null, new object[] { CodeMessage.InternalError, MessageType.Error, args.Exception });
args.FlowBehavior = FlowBehavior.Return;
}
MethodInfo.Invoke
returns an object
. Since MethodExecutionArgs.ReturnValue
is also only an object
, you don't need to cast to the actual TResponse
type.
Anyway, if you need to set some additional properties on the return value, I would introduce a non-generic interface for TResponse<T>
. You could then cast the result value to this interface and set the properties.