доступ к BackgroundService с контроллера в ядре asp.net 2.1

Мне просто нужно получить доступ к моему BackgroundService с контроллера. Поскольку BackgroundServices вводятся с

services.AddSingleton<IHostedService, MyBackgroundService>()

Как я могу использовать его из класса контроллера?


person Alex Troto    schedule 28.03.2018    source источник
comment
добавить конструктор в контроллер public ControllerName(IHostedService service){ .. } Пробовали ли вы читать документацию, прежде чем спрашивать здесь? docs.microsoft.com/en-us/aspnet/core/ основы/   -  person Roman Marusyk    schedule 28.03.2018
comment
Да. Мне нужно, чтобы BackgroundService был внедрен в мой контроллер, а не в интерфейс IHostedService. У меня может быть более одного BackgroundService, и все они внедряются как сервисы.AddSingleton‹IHostedService,...›()   -  person Alex Troto    schedule 28.03.2018
comment
Следует быть очень осторожным с тем, что aspnet регистрирует HostedServices как временные экземпляры. Таким образом, каждый раз, когда вы получаете экземпляр, это не тот экземпляр, для которого был вызван Start().   -  person Chris Marisic    schedule 13.11.2018


Ответы (3)


Вот как я это решил:

public interface IHostedServiceAccessor<T> where T : IHostedService
{
  T Service { get; }
}

public class HostedServiceAccessor<T> : IHostedServiceAccessor<T>
  where T : IHostedService
{
  public HostedServiceAccessor(IEnumerable<IHostedService> hostedServices)
  {
    foreach (var service in hostedServices) {
      if (service is T match) {
        Service = match;
        break;
      }
    }
  }

  public T Service { get; }
}

Затем в Startup:

services.AddTransient<IHostedServiceAccessor<MyBackgroundService>, HostedServiceAccessor<MyBackgroundService>>();

И в моем классе, которому нужен доступ к фоновой службе...

public class MyClass
{
  private readonly MyBackgroundService _service;

  public MyClass(IHostedServiceAccessor<MyBackgroundService> accessor)
  {
    _service = accessor.Service ?? throw new ArgumentNullException(nameof(accessor));
  }
}
person Doug Wilson    schedule 27.10.2018
comment
Небольшое предупреждение: после обнаружения необычного поведения имейте в виду, что хотя реализация IHostedService действует как синглтон, ее состояние будет недоступно. Например, если вы добавите private readonly Guid _id = Guid.NewGuid(); в класс службы и пронаблюдаете за ним при запуске службы и при получении через IHostedServiceAccessor, вы заметите, что это два разных значения. - person UtopiaLtd; 01.05.2019
comment
@UtopiaLtd Добавляйте фоновую службу не как Transient, а как Singleton. В документации Microsoft указано, что размещенная служба должна создавать области сама по себе, так как если вы добавите ее как Scoped, вы, вероятно, будете использовать удаленные объекты. - person RamenTurismo; 03.11.2020
comment
Начиная с .NET 5.0 API происходит от ControllerBase. Было бы лучше, если бы этот ответ касался того, как MyController, производный от ControllerBase, должен вызывать BackgroundService. - person H2ONaCl; 30.11.2020

В конце концов я ввел IEnumerable<IHostedService> в контроллер и отфильтровал по типу: background.FirstOrDefault(w => w.GetType() == typeof(MyBackgroundService)

person Alex Troto    schedule 28.03.2018

Добавьте BackgroundService в функцию ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHostedService<ListenerService>();


        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly IHostedService listenerService;

    public ValuesController(IHostedService listenerService)
    {
        this.listenerService = listenerService;
    }
}
1); }

Внедрить в контроллер:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly IHostedService listenerService;

    public ValuesController(IHostedService listenerService)
    {
        this.listenerService = listenerService;
    }
}

Я использовал BackgroundService для запуска нескольких слушателей для AWSSQS Listeners. Если потребитель хочет запустить новый прослушиватель, это можно сделать с помощью POST-сообщения методу контроллера (конечная точка).

person Sukhminder Sandhu    schedule 30.06.2019