Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is the root of all (OOP) dependencies stored?

I'm learning C# and the best practices around it.

Now that I know:

  1. Single Responsibility Principle
  2. Static class
  3. Singleton
  4. Dependency Injection

Everyone said to avoid Singleton and Static, and prefer dependency injection instead.

Now I have converted all of my classes so that they won't have to get their own data, such as removing:

_myItem = Repository.Instance.FindById(1);

and instead injecting my dependency inside MyClass.

public MyClass(Repository repository) {
    _myItem = repository.FindById(1);
}

However, now that MyClass following Single Responsibility Principle, and getting all dependencies from outside MyClass, what/which class will be responsible to giving all the dependencies?

My example problem in Unity is:

  • UIStatusPanelClass depend on CurrentCharacter.
  • GameInputClass depend on CurrentCharacter and CurrentCamera.
  • CharacterManagerClass hold the CurrentCharacter, but isn't responsible to pass to other class, as its single responsibility is to hold all the character in scene.
  • UIInventoryClass depend on InventoryClass, which is hold by CurrentCharacter.
  • StatisticClass depend on CurrentCharacter.
  • ItemRepositoryClass is responsible to hold List but not responsible to get the item.

Please help me straighten my knowledge of these things.

like image 299
Kevin Tanudjaja Avatar asked Aug 15 '19 09:08

Kevin Tanudjaja


1 Answers

now that MyClass following Single Responsibility Principle, and getting all dependencies from outside MyClass, what/which class will be responsible to giving all the dependencies?

This is the function of the Composition Root:

A Composition Root is a (preferably) unique location in an application where modules are composed together.

A Composition Root is located inside the application root.

A DI Container is a useful, but optional tool that can play the role as composition engine. Applying DI without a DI Container is a practice called Pure DI. If you use a DI Container, it can be considered to be part of your Composition Root.

One warning about the following code:

public MyClass(Repository repository) {
    _myItem = repository.FindById(1);
}

When practcing DI, injection constructors should be free of any logic, and should do nothing more than just store their incoming dependencies. This means that you shouldn't call FindById from within MyClass's constructor. This should be done in a later stage; in one of MyClass's methods.

like image 62
Steven Avatar answered Oct 28 '22 21:10

Steven