1: UI code. Your game objects, in general, should not know anything about your game's UI, but they should offer up all the hooks they need to for your game's UI to control them as needed.

2: Editor tools. This one is enforced by the compiler, because runtime code can't know about editor code. But the same concept as the above applies.

Click to expand...

Those are both true and inversion of control does apply here. I'm not that sure about dependency injection though. Mainly because of this disadvantage:
"Dependency injection can make code difficult to trace (read) because it separates behavior from construction. This means developers must refer to more files to follow how a system performs."

Though it does seem that dependency injection is a fairly wide term. Supplying a component through the constructor seems perfectly fine in any case to me, but that's maybe because I'm just used to that. You can throw exceptions if the parameters are required and null and skip any null testing during actual use.

In the framework design version, things get passed automatically based on requirements, which in my opinion has the above disadvantage of more difficult tracing through the code.

I use it often as it gives me more controll. I just wrote this code below in another Thread. This is how I often setup projects and where I use dependency injection. I don't like to relate on Unitys code execution.

I often have a Controller and one or different Entities which relate to it. Either the controller generates the entities or gets its references in the scene. Entity then recieves its controller and all other dependencies it needs.

That in my opinion is the reverse of inversion of control what dependency injection should do. Now the GameManager specifically knows that there is a EnemiesController and FancyStuffController. I'd have those controllers look up the GameManager singleton. That way you can be flexible in which controllers are in the scene.

I'd have those controllers look up the GameManager singleton. That way you can be flexible in which controllers are in the scene.

Click to expand...

But that is not how dependecy injection works, it's the exact opposite.

I don't know the automated way you describe, but from that little ASP code I wrote myself there always where a point where I had to supply an object with a method. Maybe you talk about things like the parameters of a Controller method? That is certainly a fundamentally different concept.
You could also use things like BroadcastMessage for instance, Event handlers or work with the
params keyword for passing objects.

You could handle it optionally as well or simply supply a null parameter.
GameManager could simply do this. At some point you have to deal with references, but Singleton is the opposite of injection.

Adding: I prefer to write code which does not have to much uncertainty in terms of if specific features or components exist or not. Maybe that is a difference, if you want to achieve something that is more generic then you can go with the Singleton Pattern. It is great for prototyping of course but can make things complicated on bigger projects.

I also make use of what you described but only for Debug and Test purposes or simply Editor code.

That in my opinion is the reverse of inversion of control what dependency injection should do. Now the GameManager specifically knows that there is a EnemiesController and FancyStuffController. I'd have those controllers look up the GameManager singleton. That way you can be flexible in which controllers are in the scene.

Click to expand...

It depends what kind of GameManager that is.
It's a matter of what you define it to be.

GameManager is a very generic term, and you can either use it at the bottom of a whole module/component that anything depends on and has access to.
Or you use it as the "master" that manages and coordinates the existing components.

In his example, it looks like it's more application specific that kind of coordinates more self-contained components.

For instance, if the Enemies type is some kind of manager itself - which it appears to be - it might be be self-contained, so knowing about the GameManager (something that could be very application specific) is nothing it should care about.

I've long struggled with exactly that, with the decision how to consistenly structure my framework.
I've come to the conclusion I'd have more freedom if i choose the latter. The smaller components are self-conained and are used by a more specific (yet general-purpose) manager. This applies to many things in the real-world anyway and therefore can be translated into OO structures very clearly, without it being a mess.

If i ever need to use an instance of that component - that is, only this specific component - I can do it without the need for the managers.

In contrast to that, if I needed a manager for my handler to work, well... it's IMO not as flexible and brings lots of limitations - at least for something you want to generalize.

In regards to very application-specific implementations - I'd probably be way less critical about such decisions.

Yes, Suddoha, I think the bottom line is that you should not focus on one architecture for everything. If indeed EnemiesController is generic with a project specific implementation, the solution is fine. But if I see the code above, it itches to create an abstract Controller class on top of CameraController, EnemiesController and FanceStuffController and change the variable of GameManager into List<Controller>. Central control, but being flexible in what it controls. Much like a plugin system really.

But if I see the code above, it itches to create an abstract Controller class on top of CameraController, EnemiesController and FanceStuffController and change the variable of GameManager into List<Controller>. Central control, but being flexible in what it controls. Much like a plugin system really.

Click to expand...

That would be another option but basically is what I have described with Controller and Entity relationship.
If you want to go fully felxible then you would have to programm a system like this. But I would not do that just for the sake of it, only use it if it is necessary.

But back to your example, in contrast to IDamagable you can use a Damagable component. This could be done in various ways, e.g. like so:

But that is not how dependecy injection works, it's the exact opposite.

Click to expand...

I don't know; I kind of agree with jvo3dc. I'd have to see more code to know what is actually happening there, but it seems like GameManager allows access to all the Controllers and all the Controllers have access to GameManager, which means everything is dependent on everything. That's the exact problem that dependency injection is supposed to solve. If everything's dependent on everything then you might as well just make GameManager a Singleton.

I don't know; I kind of agree with jvo3dc. I'd have to see more code to know what is actually happening there, but it seems like GameManager allows access to all the Controllers and all the Controllers have access to GameManager, which means everything is dependent on everything. That's the exact problem that dependency injection is supposed to solve. If everything's dependent on everything then you might as well just make GameManager a Singleton.

Click to expand...

It's actually meant to prevent Singleton not how the relationship looks like. GameManager of course is the high level class in this example. The idea would be that you go down the hierarchy and at every step you hide more and more of the higher level objects. I also often use it to make it simpler, just because I inject GameManger doesn't mean that I store it inside but rather grab 2 or 3 of its public members.

I only give my view, I used Singletons excessively in a recent project and it ended up in a mess, not using it, only for a few select classes, was a great step forward. In the end it depends on the kind of project.

It's actually meant to prevent Singleton not how the relationship looks like. GameManager of course is the high level class in this example. The idea would be that you go down the hierarchy and at every step you hide more and more of the higher level objects. I also often use it to make it simpler, just because I inject GameManger doesn't mean that I store it inside but rather grab 2 or 3 of its public members.

I only give my view, I used Singletons excessively in a recent project and it ended up in a mess, not using it, only for a few select classes, was a great step forward. In the end it depends on the kind of project.

Click to expand...

That makes sense, but I would just pass the "2 or 3 public members" directly instead of passing everything via GameManager every time. To me, half the point of dependency injection is to let you easily see what something's dependencies are, and having a constructor or initialization method that takes the dependencies as parameters is pretty simple. Always passing everything to everything and hiding what you're actually dependent on kind of makes that harder to do without any real benefit.

I think I understand what "Dependency Injection" is from everything I've been reading.
The OP provides the example code showing uses of Interfaces (for decoupling). Not using Interfaces would result in coupled code. How does not using the interface approach have to result in using dependency injection?
The OP is asking "should I use dependency injection or this interface? ". I guess I just don't fully understand the question.