I have a service which is used to get some information and the method has a bunch of async calls in the chain.
public interface IFooService
{
Task<IFoo> GetFooAsync();
}
The concrete class,
public class FooService : IFooService
{
public async Task<IFoo> GetFooAsync()
{
// whole bunch of awaits on async calls and return IFoo at last
}
}
I register this service on StartUp,
services.AddTransient<IFooService, FooService>();
Several other services are injected with this service. One among them,
public class BarService : IBarService
{
private readonly IFooService _fooService;
public BarService(IFooService fooService)
{
_fooService = fooService;
}
public async Task<IBar> GetBarAsync()
{
var foo = await _fooService.GetFooAsync();
// additional calls & processing
var bar = SomeOtherMethod(foo);
return bar;
}
}
IFoo is integral to the application and used across several services. Most of my code is async just due to this one IFooService and the one method it has which returns IFoo.
Considering this use case, I would like to be able to just inject IFoo to all other services as opposed to injecting them with IFooService.
I gave this a shot,
services.AddTransient<IFoo>(provider =>
{
var fooService = provider.GetService<IFooService>();
var foo = fooService.GetFooAsync().GetAwaiter().GetResult();
return foo;
});
but it raises a red flag to me as I'm doing sync over async and I'm unsure if this will cause any issues like race conditions. Would startup be blocked by doing this. Im looking for a clean way to handle this, any recommendation for when we need something like this? Thank you for your help.
Task<IFoo>rather than anIFoo. Why is it a problem that most of your code is now async? (It may "only" be in the service ofIFooServicecurrently but does your service truly not have any other opportunities for async work to come up?)GetFoo()or just continue injectingIFooServiceand other services can always await onGetFooAsync. But I'm wondering how such a use case is generally handled where you really want to call async code withinAddTransientorAddScopedor evenAddSingleton.IFooServicedirectly, and then they'd separately callGetFooAsyncfrom inside a normal (non-Constructor) method. If you're worried about overhead of many dependencies callingGetFooAsyncwithin a given scoped instance, you could always internally cache the value in FooService.