Skip to content

02 ‐ Dependency Injection

Hobart2967 edited this page Aug 23, 2024 · 1 revision

Enabling AppHost Configure Service override

To add services to the dependency container, add a ConfigureServices method to your AppHost class:

public class GameAppHost : AppHost {
  // ...

  public override void ConfigureServices(IServiceCollection services)
  {
    // Call base.ConfigureServices to not loose any basic functionality
    base.ConfigureServices(services);
  }

  // ...

}

Adding services to the container

To add services to the container, modify the ConfigureServices method of your AppHost in the following way:

public class GameAppHost : AppHost {
  // ...

  public override void ConfigureServices(IServiceCollection services)
  {
    // ...

    // Add MyService to the dependency container.
    services
      .AddSingleton<MyService>();
  }

  // ...

}

Using services in Node Scripts

Regardless of the type of node, you can inject services inside your nodes. The mechanism behind the injection is purely available through Property Injection, as Godot reserves the constructors of the node classes for itself. Also, you need to make sure to have called the WireNode extension method to have our AppHost pick up the node for injecting all the properties.

To use this, just add an [Inject] attribute to your properties:

using GoDough.Composition.Attributes;
using GoDough.Composition.Extensions;

public partial class MyNode : Node {
  // Add [Inject] property to any injected service
  [Inject]
  public MyService Logger { get; set; }

  public override void _Ready() {
    this.WireNode(); // Always call WireNode to make sure that the dependencies are loaded.
  }
}

Using Service Factories

  1. Call services.AddFactory with the Class Type to created inside AppHost.ConfigureServices
    services.AddFactory<ListItem>()
  2. Inject the factory and use it
    using GoDough.Composition.Attributes;
    using GoDough.Composition.Extensions;
    
    public partial class MyNode : Node {
      // Add [Inject] property to any injected service
      [Inject]
      public Factory<ListItem> ListItemFactory { get; set; }
    
      public override void _Ready() {
        this.WireNode(); // Always call WireNode to make sure that the dependencies are loaded.
    
        var listItem = this.ListItemFactory.Create();
      }
    }

Mapping a service as singleton

By default, services configured as mapped services are not hold as singleton within your dependency container. To enforce singleton mode for your service instance, you can use the MapSingleton method:

public class GameAppHost : AppHost {
  // ...

  public override void ConfigureServices(IServiceCollection services)
  {
    // ...

    // Add MyService to the dependency container.
    services
      .MapSingleton<IBootstrapper, UserBootstrapper>()
      .MapSingleton<IBootstrapper, GameDataBootstrapper>();
  }
}

This way, both UserBootstrapper and GameDataBootstrapper would be resolved as singleton instance when requiring IBootstrappers.