feat(worker,ui): wire EF Core into DI and update all consumers to IDbContextFactory
Worker and App Program.cs: replace SqliteConnectionFactory+SchemaInitializer with AddDbContextFactory<ClaudeDoDbContext> + Database.Migrate(). Repos changed from AddSingleton to AddScoped. All singleton services (QueueService, StaleTaskRecovery, WorktreeManager, TaskRunner) and singleton ViewModels (MainWindowViewModel, TaskDetailViewModel, TaskListViewModel, TaskEditorViewModel) now take IDbContextFactory<ClaudeDoDbContext> and create short-lived contexts per operation. Test infrastructure: DbFixture now uses EF migrations instead of SchemaInitializer; all test classes create contexts via DbFixture.CreateContext(). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
using ClaudeDo.Data;
|
||||
using ClaudeDo.Data.Models;
|
||||
using ClaudeDo.Data.Repositories;
|
||||
using ClaudeDo.Worker.Config;
|
||||
using ClaudeDo.Worker.Runner;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace ClaudeDo.Worker.Services;
|
||||
|
||||
@@ -14,7 +16,7 @@ public sealed class QueueSlotState
|
||||
|
||||
public sealed class QueueService : BackgroundService
|
||||
{
|
||||
private readonly TaskRepository _taskRepo;
|
||||
private readonly IDbContextFactory<ClaudeDoDbContext> _dbFactory;
|
||||
private readonly TaskRunner _runner;
|
||||
private readonly WorkerConfig _cfg;
|
||||
private readonly ILogger<QueueService> _logger;
|
||||
@@ -26,12 +28,12 @@ public sealed class QueueService : BackgroundService
|
||||
private readonly SemaphoreSlim _wakeSignal = new(0, 1);
|
||||
|
||||
public QueueService(
|
||||
TaskRepository taskRepo,
|
||||
IDbContextFactory<ClaudeDoDbContext> dbFactory,
|
||||
TaskRunner runner,
|
||||
WorkerConfig cfg,
|
||||
ILogger<QueueService> logger)
|
||||
{
|
||||
_taskRepo = taskRepo;
|
||||
_dbFactory = dbFactory;
|
||||
_runner = runner;
|
||||
_cfg = cfg;
|
||||
_logger = logger;
|
||||
@@ -56,7 +58,9 @@ public sealed class QueueService : BackgroundService
|
||||
|
||||
public async Task RunNow(string taskId)
|
||||
{
|
||||
var task = await _taskRepo.GetByIdAsync(taskId);
|
||||
using var context = _dbFactory.CreateDbContext();
|
||||
var taskRepo = new TaskRepository(context);
|
||||
var task = await taskRepo.GetByIdAsync(taskId);
|
||||
if (task is null)
|
||||
throw new KeyNotFoundException($"Task '{taskId}' not found.");
|
||||
|
||||
@@ -78,7 +82,9 @@ public sealed class QueueService : BackgroundService
|
||||
|
||||
public async Task<string> ContinueTask(string taskId, string followUpPrompt)
|
||||
{
|
||||
var task = await _taskRepo.GetByIdAsync(taskId)
|
||||
using var context = _dbFactory.CreateDbContext();
|
||||
var taskRepo = new TaskRepository(context);
|
||||
var task = await taskRepo.GetByIdAsync(taskId)
|
||||
?? throw new KeyNotFoundException($"Task '{taskId}' not found.");
|
||||
|
||||
if (task.Status == Data.Models.TaskStatus.Running)
|
||||
@@ -144,7 +150,12 @@ public sealed class QueueService : BackgroundService
|
||||
|
||||
if (_queueSlot is not null) continue;
|
||||
|
||||
var task = await _taskRepo.GetNextQueuedAgentTaskAsync(DateTime.UtcNow, stoppingToken);
|
||||
TaskEntity? task;
|
||||
using (var context = _dbFactory.CreateDbContext())
|
||||
{
|
||||
var taskRepo = new TaskRepository(context);
|
||||
task = await taskRepo.GetNextQueuedAgentTaskAsync(DateTime.UtcNow, stoppingToken);
|
||||
}
|
||||
if (task is null) continue;
|
||||
|
||||
lock (_lock)
|
||||
|
||||
Reference in New Issue
Block a user