While working with Azure ServiceFabric, we are using StateManager.GetStateAsync
method to get values, The same method can be used to get the value in object type like classes.
I'm trying with below Code
var typeObj = Activator.CreateInstance(type);
var method = typeof(IActorStateManager).GetMethod(nameof(IActorStateManager.GetStateAsync));
var generic = method.MakeGenericMethod(type);
dynamic task = generic.Invoke(typeObj, new[] { stateName })
object result = await task;
With this approach, I'm getting the exception.
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146232829
HelpLink: null
InnerException: null
Message: "Object does not match target type."
Source: "mscorlib"
StackTrace: "at System.Reflection.RuntimeMethodInfo.CheckConsistency(Object target)
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)"
TargetSite: {Void CheckConsistency(System.Object)}
Most likely, a few things have been confused here. If your code is that what you are actually executing, you are over/misusing the type
variable.
Let's decide that type
is a concrete ActorStateManager
. Then
var typeObj = Activator.CreateInstance(type); // typeobj is now ActorStateManager
The error is probably here:
var generic = method.MakeGenericMethod(type);
// generic is now StateManager.GetStateAsync<ActorStateManager>
Your intent was not to create StateManager.GetStateAsync<ActorStateManager>
, but
StateManager.GetStateAsync<bool>
or StateManager.GetStateAsync<DateTime>
.
Additionally, I GetStateAsync takes an (optional?) cancellationToken as a second argument, better to be explicit when doing reflection.
So here is what you want to do I guess:
public async Task<object> TryLotsOfTypesAndIgnoreErrors(string stateName)
{
var typeObj = Activator.CreateInstance(typeof(ActorStateManager));
foreach (var typeParam in new[] {typeof(bool), typeof(string)})
{
try
{
var method = typeof(IActorStateManager).GetMethod(nameof(IActorStateManager.GetStateAsync));
var generic = method.MakeGenericMethod(typeParam);
var task = (Task) generic.Invoke(typeObj, new object[] { stateName, CancellationToken.None });
await task;
return task.GetType().GetProperty(nameof(Task<object>.Result))?.GetValue(task);
}
catch
{
// TODO: Catch only exception specific to type mismatch
}
}
return null;
}