Make DI services scoped

This commit is contained in:
Matt Parker
2025-10-18 16:20:57 +10:00
parent d90f0e6c28
commit 69d72307f0
4 changed files with 43 additions and 24 deletions

View File

@@ -14,18 +14,19 @@ public class InjectAttribute : Attribute;
public partial class DiAutoload : Node
{
private ServiceProvider? _serviceProvider;
private IServiceScope? _currentScope;
public override void _EnterTree()
{
GD.Print("[Injector] _EnterTree called");
var services = new ServiceCollection();
// Register services here
services.AddSingleton<BuildService>();
services.AddSingleton<RunService>();
services.AddSingleton<IdeFileExternalChangeHandler>();
services.AddSingleton<IdeFileSavedToDiskHandler>();
services.AddSingleton<IdeFileWatcher>();
services.AddSingleton<IdeOpenTabsFileManager>();
services.AddScoped<BuildService>();
services.AddScoped<RunService>();
services.AddScoped<IdeFileExternalChangeHandler>();
services.AddScoped<IdeFileSavedToDiskHandler>();
services.AddScoped<IdeFileWatcher>();
services.AddScoped<IdeOpenTabsFileManager>();
_serviceProvider = services.BuildServiceProvider();
GetTree().NodeAdded += OnNodeAdded;
@@ -37,6 +38,13 @@ public partial class DiAutoload : Node
}
/// The solution has changed, so reset the scope to get new services
public void ResetScope()
{
_currentScope?.Dispose();
_currentScope = _serviceProvider!.CreateScope();
}
private void OnNodeAdded(Node node)
{
// Inject dependencies into every new node
@@ -52,11 +60,18 @@ public partial class DiAutoload : Node
{
if (Attribute.IsDefined(field, typeof(InjectAttribute)))
{
var service = _serviceProvider!.GetService(field.FieldType);
if (_currentScope is null)
{
GD.PrintErr("[Injector] _currentScope was null when attempting to resolve service");
GetTree().Quit();
return;
}
var service = _currentScope!.ServiceProvider.GetService(field.FieldType);
if (service is null)
{
GD.PrintErr($"[Injector] No service registered for {field.FieldType}");
GetTree().Quit();
return;
}
field.SetValue(target, service);