IoC stands for Inversion of Control, and as you’d expect it does what it says on the tin. You invert who has control (normally over the source of some data or entity). The classic example of IoC is synchronous vs event driven programming, you give control to your components and they notify you via events, rather than keeping control and blocking on result. The software example is normally related to using a TextField (which fires an event when the input is read) rather than calling readLine().
DI, or Dependency Injection is a form a IoC that gives control of your depedencies over to some external entity (the injector). The injector framework (there are quire alot now) is responsible for configuring your depdencies based on some meta data, which up to recently has mostly been a stack of XML but now seems to be moving towards annotations (at least in Java). A poor but apt example may be the implementation of the data driver you’re using. Your code, as always, is only dependent on the data driver interface and holds an uninitialised reference to the driver it’s going to use. The XML defined which driver implementation you want to use, and the injection framework is responsible at startup for creating the instance of the driver and linking up the reference to it.
There are several places in games development where injection could be useful above and beyond the normal software engineering use cases, resource injection for instance.
I’m not sure what parallel you’re drawing with AOP though. Dependency injection is really an augmentation of existing OOM, AOP is a different way of looking at it. They don’t solve the same problem afaik.
I’m also of the opinion that DI is total junk tbh, it’s popular like many things in the enterprise world - because it ticks a technology box for architects everywhere. It’s technical merit seems pretty limited to me. The concept IoC is perfectly sound though, just the DI frameworks in existence seem to be a bit pointless.
Long live AOP! 