aldozz
aldozz
CC#
Created by aldozz on 12/16/2024 in #help
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?
4 replies