0

I do know the differences between Scoped, Singleton and Transient services lifetimes, but my knowledge is limited to a stateless, MVC application.

The root of the confusion starts when I add an EntityFramework context using AddScoped (per-request lifetime), and then, all I need to do to update my database is:

public void SaveUser()
{
    db.SaveChanges();
}

This is very different from a MVC app, because there, the objects are completely decoupled from the context when, for exemple, they are converted to JSON and sent to the client, or from client to server (or, in other words, another request is made):

public void SaveUser(User updatedUser)
{
    var existing = db.Users.Find(updatedUser.Id);
    existing.Name = updatedUser.Name;
    db.SaveChanges();
    // I can also use something like Attach() or Update() instead.
}

This is possible in Razor Components because all of the objects (that I've bound to the UI) are still being tracked by the context, in a stateful way, through SignalR. The EF Context seems to "never" be disposed.

In a MVC app, the EntityFramework context is recreated before every request, and disposed after (as you can expect from AddScoped).

So, I have three questions:

  1. What exactly is a "request" in Razor Components aka. Server Side Blazor (from the service lifetime point of view)?
  2. What about clients loosing the connection and reconnecting after?
  3. Is there any situations where I need to verify if the object is "still" being tracked by the context, or this sort of problem never happens?
Guilherme
  • 5,143
  • 5
  • 39
  • 60
  • I think you're thinking to hard about it. Razor Components are basically just a candy-coated shell covering all the same basic infrastructure that exists with any ASP.NET Core app. Requests are requests - any time the client asks the server for something. It's just you don't have to think about it as Razor Components basically abstract all the SignalR, data-binding, etc. logic you'd otherwise create yourself. There's nothing magical about it. It just seems magical. – Chris Pratt Apr 23 '19 at 19:11
  • @ChrisPratt Thanks. Indeed, it feels magical. I also feel I'm overthinking this. But could you please clarify about the service lifetime/service injection being the same as a regular Core MVC? If so, then between button clicks, I should get a fresh copy of the services injected as Scoped, right? It does not happen, as far as I've tested – Guilherme Apr 23 '19 at 19:28
  • What makes you suspect it's not happening? – Chris Pratt Apr 23 '19 at 19:31
  • I suspect that because I don't need to `Attach` the object to the context to save it. If one could see the literal lifetime in seconds of the context, on my MVC app it would be less than a second, and my RC app it would be minutes (as long as the user is connected to the SignalR hub). Am I mistaken? – Guilherme Apr 23 '19 at 19:37
  • I'm not 100% sure honestly, but I believe this too is simply abstract away. You're dealing with essentially the same C# object both server and client-side, but once exists in compiled server-side assembly while the other is in webassembly. That means there's still translation happening through a process of network communication, meaning that it's still being serialized during transit. Long and short, you sitll have a process of a network request, model-binding and attachment to the context; it's just all abstracted away from you. – Chris Pratt Apr 23 '19 at 19:45
  • I see. Just to clarify, I'm using the "server side" hosting model - neither webassembly involved, nor HTTP requests (manual requests at least). I am not using controllers or HttpClients, just injected services in the .razor files - and in those services, I inject the EF Context (all of them Scoped). – Guilherme Apr 23 '19 at 20:32

0 Answers0