How to call async method in Autofac registration?

This is an old question, but I think autofac does not support that.

We used:

builder.Register(c =>
  {
      var bar= c.Resolve<IBar>();
      var foo = new Foo(bar);
      return foo.ComputeAsync().ConfigureAwait(false).GetAwaiter().GetResult();
  })
.As<IFoo>()
.SingleInstance();

But as mentioned on the comments: Registering async factory in Autofac


I think that doing any I/O intensive work at resolution phase is wrong design, because it's usually important to have full control over the order of this operations, catch their exceptions, repeat them, control time between some of them, etc.

Solution is to postpone them with factories. Let me replace SomeClass with a more meaningful NpgsqlConnection:

var builder = new ContainerBuilder();
builder.Register(context =>
{
    // make sure not to capture temporary context:
    // https://autofaccn.readthedocs.io/en/latest/advanced/concurrency.html#service-resolution
    var connectionString = context.Resolve<IConfiguration>().GetConnectionString("MyDb");

    return new Func<Task<NpgsqlConnection>>(async () =>
    {
        var connection = new NpgsqlConnection(connectionString);
        await connection.OpenAsync();
        return connection;
    });
});

And here's how connection user can look like:

public sealed class Repository
{
    private readonly Func<Task<NpgsqlConnection>> _connectionFactory;

    public Repository(Func<Task<NpgsqlConnection>> connectionFactory)
    {
        _connectionFactory = connectionFactory;
    }

    public async Task<string> GetServerVersionAsync()
    {
        using (var openedConnection = await _connectionFactory())
            return openedConnection.ServerVersion;
    }
}

Even if Autofac would support async registrations, it is still would be beneficial to require a factory in Repository constructor, because the connection is a limited resource and it is better to limit the time it is opened.