Синглтон Websocket, который использует Scoped Service - PullRequest
0 голосов
/ 14 октября 2019

Я реализовал промежуточное программное обеспечение WebSocket, которое содержит в качестве поля одноэлементный словарь WebSocket (внедренный через конструктор) и некоторые другие параметры области действия, введенные через конструктор.

Я хотел бы знать, правильно ли оно реализовано.

public WebSocketManagerMiddleware(RequestDelegate next,
    IWebSocketConnectionDictionary webSocketDictionary,
    IScopedServiceOne scopedOneService, IScopedServiceTwo scopedtwoService)
{
    _next = next;
    _webSocketManager = webSocketDictionary;
    _scopedOneService= scopedOneService;
    _scopedtwoService= scopedtwoService;
}

В этот конструктор я добавляю следующие экземпляры:

_app.UseMiddleware<WebSocketManagerMiddleware>(
    app.ApplicationServices.GetWebSocketConnectionDictionary(),
    serviceProvider.CreateScope().ServiceProvider.GetScopedOneService(),
    serviceProvider.CreateScope().ServiceProvider.GetScopedTwoService())

Я боюсь, что каждый раз при запросе WebSocket создаю новую область, из которой я получаю сервисы с областью действия (serviceOne,serviceTwo) и никогда не удаляется, пока не будет закрыто соединение WebSocket. Поскольку я использую эти сервисы только при запуске websocket и после того, как я начинаю прослушивать будущие сообщения, я никогда не использую их (IScopedOneSerice, IScopedTwoService)

public async Task Invoke(HttpContext context, IServiceProvider service)
{
    await _scopedOneService.MethodOne();
    await _scopedTwoService.MethodTwo();
    //startint to listen for messages and if I need to call some repository 
    // method I am using 
    //IServiceProvider, i.e ISomeRepository repo =
    //    service.GetRequiredService<ISomeRepository>(); // this repo scoped as well
}

Возможно ли таким способом получить утечку памяти?

ОБНОВЛЕНО: чего я пытаюсь достичь: давайте сделаем это проще, каждый раз, когда я получаю сообщение websocket, мне нужно вставить сообщение в хранилище или разрешить некоторые другие службы, которые взаимодействуют с другими службами бизнес-логики.

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

1 Ответ

1 голос
/ 14 октября 2019

Как сказано в моем комментарии, вы должны внедрить IServiceScopeFactory вместо сервисов с определенными областями. Затем вы можете использовать это для разрешения указанных служб.

public WebSocketManagerMiddleware(RequestDelegate next,
    IWebSocketConnectionDictionary webSocketDictionary,
    IServiceScopeFactory scopeFactory)
{
    _next = next;
    _webSocketManager = webSocketDictionary;
    _scopeFactory = scopeFactory;
}

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

using (var scope = _scopeFactory.CreateScope())
{
    var scopedOneService = scope.ServiceProvider.GetRequiredService<IScopedServiceOne>();
    var scopedTwoService = scope.ServiceProvider.GetRequiredService<IScopedServiceTwo>();
    // do something with scoped services
}

Вытакже следует прочитать этот ответ , который является правильным в этом контексте, но не в контексте вопроса, за который был опубликован ответ Криса, поэтому он был отклонен:)

...