Skip to content

Scoped class in SignalR not resolving to existing one already created. #13200

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Buildstarted opened this issue Aug 16, 2019 · 8 comments
Closed
Labels
area-signalr Includes: SignalR clients and servers question
Milestone

Comments

@Buildstarted
Copy link

Describe the bug

I've created a scoped class that is populated in some middleware. This could be a settings object or permissions object or whatever.

Using the scoped object in a constructor of an mvc controller I get that value I expect. However, using the same scoped object in the constructor of a hub I get a newed up instance of the scoped class.

I have verified that the middleware is being called when the endpoint for the hub is hit.

To Reproduce

Steps to reproduce the behavior:

  1. Using this version of ASP.NET Core : 3.0 preview 8 013656 (though it affected the previous preview as well)

Gist with sample project

Expected behavior

As with MVC I expect when resolving a scoped object that it retrieves the object that has already been created and subsequently modified in the middleware.

It's possible that this is intended and if so how can I reliably retrieve scoped objects in signalr?

@Buildstarted
Copy link
Author

Looks like DI doesn't work in this context possibly due to the creation of a child scope? You can resolve dependencies via Context.GetHttpContext().RequestServices

@rynowak rynowak added the area-signalr Includes: SignalR clients and servers label Aug 17, 2019
@rynowak
Copy link
Member

rynowak commented Aug 17, 2019

What you're seeing is expected because there are two requests happening here, and thus two scopes.

  • Your original page load is a an HTTP request that gets static HTML (from MVC)
  • Then the browser sends a second HTTP request to open a websocket and connect to SignalR.

Can you prove some more information about what you want to accomplish, so we can try to help?

@Buildstarted
Copy link
Author

Right and I understand that. This was simply an example to show that MVC requests work properly to resolve the scoped dependency while a hub doesn't.

client -> middleware -> mvc (testobj is the same from middleware)
client -> middleware -> hub (testobj isn't the same from middleware for the initial connection)

Since hubs are shortlived and as time goes on the testobj from the middleware will get stale since the middleware isn't called for each message that comes through. I suppose this is why scoped depedancies are not properly resolved since each message doesn't get a full scope but it is definitely confusing.

@BrennanConroy
Copy link
Member

Because hubs are abstracted away from the underlying connection we don't know if there was a new request or the same request just streaming more data.

And because there are multiple ways to connect in SignalR (both a new http request per hub method invoke and a single long-running request for all hub method invokes) we need to treat each hub method call as a different request to have a consistent experience across different connection types.

TLDR: every hub method call we create a new service scope and resolve services from that scope.

@halter73
Copy link
Member

SignalR does not use the request DI scope. It creates its own scope per hub-invocation. This is partly due to the possibility of a single request triggering multiple invocations. Creating some sort of hub pipeline module to configure your service might be an alternative/addition to the middleware once we add a hub pipeline. #5353

@halter73 halter73 added this to the Discussions milestone Aug 20, 2019
@Buildstarted
Copy link
Author

Thanks, @halter73. Looking forward to the future. Since you don't use the underlying HttpContext how reliable is RequestServices (assuming all connections are over websockets)?

@ghost
Copy link

ghost commented Dec 6, 2019

Thank you for contacting us. Due to no activity on this issue we're closing it in an effort to keep our backlog clean. If you believe there is a concern related to the ASP.NET Core framework, which hasn't been addressed yet, please file a new issue.

@ghost ghost closed this as completed Dec 6, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 6, 2019
@dotnet dotnet unlocked this conversation Dec 6, 2019
@halter73
Copy link
Member

halter73 commented Dec 6, 2019

@Buildstarted Sorry I missed your comment until just now. SignalR manually creates a "request" scope per invocation, so it should be very reliable.

https://github.com/aspnet/AspNetCore/blob/0d02d7a7051edebf24fc2ba92d0172f741f53455/src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs#L218

@ghost ghost locked as resolved and limited conversation to collaborators Jan 5, 2020
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-signalr Includes: SignalR clients and servers question
Projects
None yet
Development

No branches or pull requests

4 participants