Как сделать так, чтобы постоянная фоновая задача сигнализировала о выделенной службе в ядре asp.net? - PullRequest
0 голосов
/ 01 марта 2019

В моем веб-приложении ASP.NET Core 2.2 у меня есть следующие сервисы в моём методе Startup.ConfigureServices (IServiceCollection services):

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();

    services.AddScoped<WebApplication.Services.DoThingAlpha>();
    services.AddScoped<WebApplication.Services.DoThingBravo>();
    services.AddScoped<WebApplication.Services.DoThingCharlie>();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Эти сервисы в области делают грязную работу для моих контроллеров.

Однако мне необходимо постоянно прослушивать UDP-порт в фоновом режиме, а затем уведомлять соответствующую службу (DoThingsAlpha, DoThingsBravo или DoThingsCharlie) при получении определенных сообщений UDP на слушателе.

Я думаю, что я могу реализовать фоновый сервис с BackgroundService (https://docs.microsoft.com/en-us/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/background-tasks-with-ihostedservice), а затем добавить в коллекцию сервисов в ConfigureServices. Давайте назовем его ListenOnUDP: BackgroundService

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

1 Ответ

0 голосов
/ 14 марта 2019

Я разработал решение, и я думаю, что проблема возникла из-за моего глубокого непонимания служб ASP.NET Core.Я объясню на случай, если у кого-то возникнет такая же проблема (или, возможно, подтвердите или лишите законной силы мой ответ).

Когда вы добавляете класс / интерфейс службы в свою коллекцию IServiceCollection, эта служба становится доступной для других служб через интерфейс.Вы просто включаете интерфейс в конструктор другого сервиса, который вы хотите вызвать в своем конструкторе, сохраняете его, и затем вы можете вызывать интерфейс (что я понимаю, это проявление внедрения зависимости).Примерно так:

    private readonly InterfaceRCResponseQueue _rcResponseQueue;
    private readonly ILogger _logger;

    public UdpListenerBackgroundService(
        InterfaceRCResponseQueue rcResponseQueue,
        ILogger<UdpListenerBackgroundService> logger
        )
    {
        _rcResponseQueue = rcResponseQueue;
        _logger = logger;
    }

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

Перехват:

Одиночная служба не может зависеть отограниченный или временный сервис.Предположительно, потому что это зависает в области обслуживания или переходного периода.И наоборот, все в порядке.

https://blog.markvincze.com/two-gotchas-with-scoped-and-singleton-dependencies-in-asp-net-core/

В моем случае у меня есть класс UdpClient, который должен прослушивать сообщения и затем сигнализировать другим службам.

Для выполненияИтак, я поместил свой класс UdpClient в класс, который наследуется от Microsoft.Extensions.Hosting.BackgroundService и, следовательно, создается и разрушается при жизни приложения.Я также создал одноэлементный класс, который содержит очередь.

Когда мой класс UdpClient в моем классе BackgroundService получает дейтаграмму UDP, я вызываю метод в одноэлементном классе, который ставит его в очередь в одноэлементном классе.

Класс scoped, singleton или transient может зависеть от класса singleton и искать данные в этой очереди (в очереди) на досуге.Вы просто не можете сделать обратное (сделать так, чтобы синглтон зависел от ограниченного или транзитивного сервиса).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...