Simplifying Dependency Injection
After one of those suggestions you hear and think “That’s just brilliant!”, I decided to make dependency injection in my Apollo entities a nearly invisible process. The idea is that I search over all of a component’s properties when it is added to an entity and any property whose type inherets from EntityComponent is assumed to be desired for dependency injection. So I can now have these two classes:
[Unique]
public class MyComp1 : EntityComponent
{
public float A { get; set; }
public float B { get; set; }
}
public class MyComp2 : EntityComponent
{
public MyComp1 Comp1 { get; set; }
}
And when I add MyComp2 to the entity, it’s Comp1 property will automatically be set to the instance of MyComp1. There are a couple caveats, however:
1) Order of adding is important. The system no longer tries to instantiate components that aren’t added and instead throws an exception. So with my example, I’d have to add a MyComp1 object to an entity before a MyComp2 object or else it’ll throw an exception.
2) Components still need a UniqueAttribute on them if they’re to be used for dependency injection. At this point I’m not sure of a situation where you need multiple components of the same type, so I may move away from this in the future and simply enforce a mandatory uniqueness rule.
I also have an OptionalAttribute that can be placed on a property if that dependency injection is optional. If a property has the OptionalAttribute and a matching component can’t be found, it simply leaves the property alone rather than throwing an exception.
All in all I’m pretty happy with it. Still more work to do, but it’s certainly getting there. One thing I’m planning to work on is an “Entity Editor”, which is going to be some sort of WinForm app (or Visual Studio add-on if I ever get learn how those are done) that lets you visually design components and entity blueprints that you can then use in game.
As with all my code these days, the entity stuff can be found in my Apollo repository. Again, the code is under the “do whatever with it, but don’t blame me if it breaks and it’d also be nice if you credit me” license. And again, there are classes in there that are very much works-in-progress so if you see something that looks like it doesn’t do anything, isn’t used, or doesn’t work that’s probably why.

A particle system may be an example of a component which you may want multiple instances of attached to a single entity.
With instances such as multiple particle systems in mind, perhaps the better method is by default enforce unique with an attribute that allows multiple instances?