1
votes

So I have the following scenario

  • A MVC Site
  • A Hub
  • A IUnitOfWork interface with an implementation that instantiates an EF 6 context in the constructor
  • Ninject as DI where IUnitOfWork is registered as InRequestScope

TLDR: Why is signalr preserving it's dependencies per connection? and not per request?

I originally made the site with mvc 3 and implemented the following https://stackoverflow.com/a/22750142/28145

from this post SignalR 2 Dependency Injection with Ninject

the accepted answer on this post is now http://www.tomdupont.net/2014/01/dependency-injection-with-signalr-and.html

But both implementations appears to have no effect on my problem.

My site has been migrated to mvc 4 and currently now is mvc 5 and has been for ages.

I've just now discovered this problem because I've never triggered data changes from the client to the signalr hub.

The way I validated this was by giving my IUnitOfWork implementation an ID that got generated in the constructor.

Reproduction Steps:
You enter the mvc page/site/action and gets the html page rendered, the html page connects to your hub and the IUnitOfWork is instantiated, you can do some queries and return some data.

Another user enters the site on the same hub and queries some data aswell.

When inspecting the IUnitofWork identifier when the first user connected, the identifier had the value 1

The first user executes a serverside action on the hub, this action

  • Fetches data from the db
  • Compares the data to decide on what action to take
  • Then changes the data
  • Lets say it sets the property Broken = true, where it was false before.
  • Notice that the identifier for IUnitOfWork on this new request is still 1

The IUnitOfWork identifier when the second user loaded the page is 2, this page was loaded before the first user peformed his action.

Now the second user on the other connection executes a serverside action on the hub. this action relies on the data from the first user, it queries the IUnitOfWork, and thereby the DbContext for the property Broken. to my surprise the value of Broken = false, as a result the action does nothing. The IUnitOfWork identifier during the action is still 2

The second user now refreshes the page with F5, and as a result signalr creates a new connection. The IUnitOfWork identifier is now 3

the second user tries to execute that function again. but this time the query returns Broken = true, as expected. while the IUnitOfWork identifier is still 3. the reason being that the context was initialized after the first users action had changed data.

1

1 Answers

0
votes

Its extremely hard to give an accurate answer without seeing any code, but my guess would be that you are not recreating the SQLDependency trigger and/or re- attaching the event handler. SQLDT's are a one shot deal, if you don't recreate them they never fire again, The second user loading the page is recreating the new trigger in the initialization, and the same for the page refresh, once you refresh a page its a disconnect and a reconnect with a new connectionid and a new trigger.