Getting started

edit

Install the package

dotnet package add Meziantou.Framework.ObjectMethodExecutor

ObjectMethodExecutor is in the Meziantou.Framework namespace. The examples of this documentation omit the using directives, and check their results with assertions such as Assert.Equal.

Call a method

Given a class:

public sealed class Sample
{
    public int Offset { get; init; }

    public async Task<int> AsyncMethod(int a, int b)
    {
        await Task.Yield();
        return Offset + a + b;
    }
}

Create an executor from the MethodInfo of the method, then call it with the instance and the arguments:

var methodInfo = typeof(Sample).GetMethod(nameof(Sample.AsyncMethod))!;
var executor = ObjectMethodExecutor.Create(methodInfo);

var instance = new Sample { Offset = 10 };
var parameters = new object?[] { 1, 2 };
if (executor.IsMethodAsync)
{
    // You can call ExecuteAsync even if the underlying method is not async.
    // It returns an awaitable that completes with the return value of the method.
    var result = await executor.ExecuteAsync(instance, parameters);
    Assert.Equal(13, result);
}
else
{
    var result = executor.Execute(instance, parameters);
    Assert.Equal(13, result);
}
  • ObjectMethodExecutor.Create inspects the method and compiles a delegate to call it. Create the executor once and reuse it: the creation is the expensive part.
  • IsMethodAsync is true when the method returns an awaitable type.
  • Execute calls the method and returns its return value, or null for a void method.
  • ExecuteAsync returns an awaitable that completes with the result of the method once it is awaited.
  • The target is the instance; pass null for a static method.

You can call ExecuteAsync for every method, even a synchronous one: the awaitable then completes with the return value.

Next steps