C
C#6d ago
aldozz

Why using is used here

I have a piece of code I'm studying here from a course (I cannot contact the author), it's a .NET 9 app that uses IServiceScopeFactory of .NET dependency injection package
public class OutboxWorker(ILogger<OutboxWorker> logger, IServiceScopeFactory serviceScopeFactory, IEventPublisher eventPublisher) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using (IServiceScope scope = serviceScopeFactory.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<OrdersDbContext>();
var outboxItems = db.Outbox.Where(item => !item.Processed);

foreach (var item in outboxItems)
{
logger.LogInformation("some operation is done")
item.Processed = True
break;
}

db.Outbox.Update(item);
}

await db.SaveChangesAsync(stoppingToken);
}

await Task.Delay(5000, stoppingToken);
}
}
}
public class OutboxWorker(ILogger<OutboxWorker> logger, IServiceScopeFactory serviceScopeFactory, IEventPublisher eventPublisher) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using (IServiceScope scope = serviceScopeFactory.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<OrdersDbContext>();
var outboxItems = db.Outbox.Where(item => !item.Processed);

foreach (var item in outboxItems)
{
logger.LogInformation("some operation is done")
item.Processed = True
break;
}

db.Outbox.Update(item);
}

await db.SaveChangesAsync(stoppingToken);
}

await Task.Delay(5000, stoppingToken);
}
}
}
I got two questions: 1. Why does the CreateScope() have to be inside a using? I understand that using using ensures the Dispose method is called, but I cannot rationalize a use case where this would be applicable. Could someone help me with a use case/simple code snippet where this will be important (and thus wrapping around using is beneficial)? 2. Why do we still need dto call db.SaveChangesAsync() even after db.Outbox.Update(item) is called? I understand that this would be needed if item is not tracked by EF Core? But I thought all items inheriting DbContext would be auto tracked? Would someone help with a code snippet/use case/scneario where an item needs to be untracked and thus this extra call is needed?
1 Reply
mg
mg6d ago
1. simplest answer is that IServiceScope implements IDisposable, so it should be disposed of when you're done with it. as for why it's disposable, it's so that any services that need to be disposed of when you're done with the scope are disposed of 2. something being tracked just means that your DbContext is aware of them. their tracking state could be any of detached, unchanged, added, deleted, or modified. SaveChangesAsync() is what actually writes the changes you've made to the database worth noting that db.Outbox.Update() is unnecessary. the changes to each item.Processed will be tracked when the property is changed though you break after one iteration, so only one item will actually get updated
Want results from more Discord servers?
Add your server