Вызов асинхронного метода в AddTransient при запуске - Asp.Net Core - PullRequest
0 голосов
/ 24 января 2019

У меня есть служба, которая используется для получения некоторой информации, а метод содержит несколько асинхронных вызовов в цепочке.

public interface IFooService
{
    Task<IFoo> GetFooAsync();
}

Класс бетона,

public class FooService : IFooService
{
    public async Task<IFoo> GetFooAsync()
    {
        // whole bunch of awaits on async calls and return IFoo at last
    }
}

Я регистрирую эту услугу при запуске,

services.AddTransient<IFooService, FooService>();

Несколько других сервисов внедряются с этим сервисом. Один из них,

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 является неотъемлемой частью приложения и используется несколькими службами. Большая часть моего кода async только из-за этого IFooService и единственного метода, который возвращает IFoo.

Учитывая этот вариант использования, я хотел бы иметь возможность просто внедрить IFoo во все другие службы, а не внедрять их с помощью IFooService.

Я дал этому выстрел,

services.AddTransient<IFoo>(provider => 
{
    var fooService = provider.GetService<IFooService>();
    var foo = fooService.GetFooAsync().GetAwaiter().GetResult();
    return foo;
});

, но он поднимает мне красный флаг, так как я выполняю синхронизацию по асинхронности, и я не уверен, вызовет ли это какие-либо проблемы, такие как условия гонки. Будет ли запуск заблокирован при этом. Я ищу чистый способ справиться с этим, любые рекомендации, когда нам нужно что-то подобное? Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 25 января 2019
services.AddTransient<IFoo>(provider =>
{
    var fooService = provider.GetService<IFooService>();
    var foo = fooService.GetFooAsync().GetAwaiter().GetResult();
    return foo;
});

Эта опция немного лучше, чем .Result, так как .Result обернет все ваши исключения в AggregateException, и у вас не будет этого побочного эффекта с кодом, который я предложил.Также не забывайте, что обе опции не будут работать асинхронно, они будут работать синхронно, блокируя поток

0 голосов
/ 25 января 2019

но он поднимает красный флаг для меня, так как я делаю синхронизацию по асинхронному

Для этого красного флага это вызвано тем, что вы вызываете метод GetFoo, который не являетсяопределенный в IFooService, он не связан с асинхронным или синхронизирующим методом.

Попробуйте метод, который определен

services.AddTransient<IFoo>(provider =>
{
    var fooService = provider.GetService<IFooService>();
    var foo = fooService.GetFooAsync().Result;
    return foo;
});
...