Websocket singleton who uses Scoped Service

*爱你&永不变心* 提交于 2020-01-06 08:17:30

问题


I have implemented WebSocket middleware who has contains as a field singleton WebSocket dictionary(injected via constructor) and some other scoped parameters injected via constructor.

I would like to know if it's implemented correctly.

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

To this constructor, I am injecting these instances like this:

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

I am afraid that I every time on WebSocket request create new scope from where I am getting scoped services(serviceOne, serviceTwo) and it never disposed until WebSocket connection is closed. Because I am using these services only on the websocket start and after I starting to listen to upcoming messages I never use them (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
}

Is it possible to get any memory leak this way?

UPDATED: What I am trying to achieve: let's make it simple, every time I get a websocket message I need to insert the message to the repository or resolve some other services who communicates with other business logic services.

I am not sure what is the best approach to inject scoped serviecs into websocket middleware who contains singleton websocket dictionary and some other scoped services.


回答1:


As said in my comment, you should inject an IServiceScopeFactory instead of the scoped services. You can then use that to resolve the scoped services.

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

You can then create a new scope and resolve the service from there whenever you need to access them.

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

You should also read this answer which is correct in this context but not in the context of the question Chris' answer was posted for, that's why it's been downvoted :)



来源:https://stackoverflow.com/questions/58376514/websocket-singleton-who-uses-scoped-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!