Files
SharpIDE/src/SharpIDE.Godot/DiAutoload.cs
2025-10-19 11:27:06 +10:00

84 lines
2.7 KiB
C#

using Godot;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using SharpIDE.Application.Features.Analysis;
using SharpIDE.Application.Features.Build;
using SharpIDE.Application.Features.FilePersistence;
using SharpIDE.Application.Features.FileWatching;
using SharpIDE.Application.Features.Run;
namespace SharpIDE.Godot;
[AttributeUsage(AttributeTargets.Field)]
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.AddScoped<BuildService>();
services.AddScoped<RunService>();
services.AddScoped<IdeFileExternalChangeHandler>();
services.AddScoped<CodeActionService>();
services.AddScoped<FileChangedService>();
services.AddScoped<IdeFileWatcher>();
services.AddScoped<IdeOpenTabsFileManager>();
services.AddScoped<RoslynAnalysis>();
_serviceProvider = services.BuildServiceProvider();
GetTree().NodeAdded += OnNodeAdded;
GD.Print("[Injector] Service provider built and NodeAdded event subscribed");
}
public override void _Ready()
{
}
/// 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
InjectDependencies(node);
}
private void InjectDependencies(object target)
{
var type = target.GetType();
const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
foreach (var field in type.GetFields(flags))
{
if (Attribute.IsDefined(field, typeof(InjectAttribute)))
{
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);
}
}
}
}