Entity Factories can also act as builders, allowing step-by-step configuration before creation. This approach is especially useful when entities require external dependencies or custom initialization.
A Builder version of an entity factory lets you configure parameters using fluent Set... methods before calling
Create().
public sealed class PlayerContextBuilder : IEntityFactory<PlayerContext>
{
private GameContext _gameContext;
private TeamType _teamType;
private Camera _camera;
public PlayerContextBuilder SetGameContext(GameContext gameContext)
{
_gameContext = gameContext;
return this;
}
public PlayerContextBuilder SetTeamType(TeamType teamType)
{
_teamType = teamType;
return this;
}
public PlayerContextBuilder SetCamera(Camera camera)
{
_camera = camera;
return this;
}
public override PlayerContext Create()
{
if (_camera == null)
throw new InvalidOperationException("Camera must be set before creating PlayerContext.");
if (_teamType == default)
throw new InvalidOperationException("TeamType must be set before creating PlayerContext.");
var playerContext = new PlayerContext();
playerContext.AddValue("TeamType", _teamType);
playerContext.AddValue("GameContext", _gameContext);
playerContext.AddValue("Camera", _camera);
return playerContext;
}
}Usage example:
var playerContext = new PlayerContextBuilder()
.SetGameContext(gameContext)
.SetTeamType(teamType)
.SetCamera(camera)
.Create();💡 In this pattern, the factory provides
Set...methods to configure dependencies,
and the finalCreate()call produces a fully initializedPlayerContext.
You can also apply the builder pattern to singleton-style factories — useful for centralized systems like GameContext.
public class GameContextBuilder : IEntityFactory<GameContext>
{
private string _name = "DefaultGame";
private int _tagCapacity = 4;
private int _valueCapacity = 8;
private int _behaviourCapacity = 4;
public GameContextBuilder WithName(string name)
{
_name = name;
return this;
}
public GameContextBuilder WithTagCapacity(int capacity)
{
_tagCapacity = capacity;
return this;
}
public GameContextBuilder WithValueCapacity(int capacity)
{
_valueCapacity = capacity;
return this;
}
public GameContextBuilder WithBehaviourCapacity(int capacity)
{
_behaviourCapacity = capacity;
return this;
}
public GameContext Create()
{
return new GameContext(_name, _tagCapacity, _valueCapacity, _behaviourCapacity);
}
}Registering the Builder
var builder = new GameContextBuilder()
.WithName("GameContext")
.WithTagCapacity(16)
.WithValueCapacity(32)
.WithBehaviourCapacity(8);
GameContext.SetFactory(builder);Using the Context
GameContext context = GameContext.Instance;
context.AddValue("Score", 42);
context.AddBehaviour<EnemySpawnBehaviour>();
context.Init();- Factories handle simple, immediate creation.
- Builders extend factories with configuration steps for more flexible and testable initialization.
- This pattern helps you:
- Avoid constructor overload chaos.
- Support dependency injection.
- Keep your entity creation process explicit and safe.