IssueRaiser

[API Proposal]: Asynchronous DI support

### Background and motivation There are cases where it is necessary to inject a dependency as a result of an asynchronous operation. This usually comes up when the dependency requires input from some IO operation (like retrieving a secret from a remote store). Today, developers tend to put blocking calls in factories: ```C# var services = new ServiceCollection(); services.AddSingleton<IRemoteConnectionFactory, RedisConnectionFactory>(); services.AddSingleton<IRemoteConnection>(sp => { var factory = sp.GetRequiredService<IRemoteConnectionFactory>(); // NOOOOOO 😢 return factory.ConnectAsync().Result; }); ServiceProvider sp = services.BuildServiceProvider(); IRemoteConnection connection = await sp.GetRequiredServiceAsync<IRemoteConnection>(); public interface IRemoteConnection { Task PublishAsync(string channel, string message); Task DisposeAsync(); } public interface IRemoteConnectionFactory { Task<IRemoteConnection> ConnectAsync(); } ``` The only other viable solution is to move that async operation to method calls, which results in deferring all IO until methods are called (where things can truly be async). This is a non-trivial refactoring that might be impossible depending on the circumstance. The idea here is to provide asynchronous construction support, so that these scenarios can work. ### API Proposal #### Async Resolution Support ```C# namespace Microsoft.Extensions.DependencyInjection; public class ServiceDescriptor { public st

Posted by davidfowl on Feb 21, 2022, 5:25 AM

Tags

Related issues

Raise real-world problems, find people facing the same issue, and discuss solutions.2,500 issues0 comments

support (Other)

[API Proposal]: Asynchronous DI support

davidfowlFeb 21, 2022, 5:25 AM

### Background and motivation There are cases where it is necessary to inject a dependency as a result of an asynchronous operation. This usually comes up when the dependency requires input from some IO operation (like retrieving a secret from a remote store). Today, developers tend to put blocking calls in factories: ```C# var services = new ServiceCollection(); services.AddSingleton<IRemoteConnectionFactory, RedisConnectionFactory>(); services.AddSingleton<IRemoteConnection>(sp => { var factory = sp.GetRequiredService<IRemoteConnectionFactory>(); // NOOOOOO 😢 return factory.ConnectAsync().Result; }); ServiceProvider sp = services.BuildServiceProvider(); IRemoteConnection connection = await sp.GetRequiredServiceAsync<IRemoteConnection>(); public interface IRemoteConnection { Task PublishAsync(string channel, string message); Task DisposeAsync(); } public interface IRemoteConnectionFactory { Task<IRemoteConnection> ConnectAsync(); } ``` The only other viable solution is to move that async operation to method calls, which results in deferring all IO until methods are called (where things can truly be async). This is a non-trivial refactoring that might be impossible depending on the circumstance. The idea here is to provide asynchronous construction support, so that these scenarios can work. ### API Proposal #### Async Resolution Support ```C# namespace Microsoft.Extensions.DependencyInjection; public class ServiceDescriptor { public st

Comments (0)

No comments yet. Start the discussion.

Comment on this issue