Search code examples
c#dependency-injectionsolid-principles

Dependency Injection Problems


I've got into dependency inversion principle and inversion of control just recently, and from what I currently know(correct me if I'm wrong) is that DIP states that

high level module/class should not be dependent upon the low-level module/class

both high and low-level module should not depend on details(not sure what this one means???), but abstractions(interfaces)

but when I was writing a simple program to implement this principle, i ran into a problem(will explain it later)

My program consist of an Inventory and Player class that implements "ICharacterable"

      class Player : ICharacterable {

    private int _health = 100;

    public int Health{

        get{
            return _health;
        }

    }

    public int HealthIncrease(int health){
        //increase health
        return _health + health;

    }


}

class Inventory{

    ICharacterable player = null;

    //constructor injection
    public Inventory(ICharacterable player) {

        this.player = player;

    }

    //increase player health
    public void UseHealthPotion(int health) {

        player.HealthIncrease(health);

    }

}

class Program{
static void Main(string[] args) {

    Player john = new Player();
    Inventory inv = new Inventory(john);

    inv.UseHealthPotion(30);
    Console.WriteLine(john.Health);
     
}

}
 
 //interface
public interface ICharacterable {

    int HealthIncrease(int health);

}

the problem is, the Console returns 100 instead of 130. I figure that the problem was caused due to the fact that I declared was injecting a ICharacterable type instead of Player(but that would violate the DIP), is there anyway I could do this? Thanks


Solution

  • You get bad result, because your method only returns result of the addition and not change a state of the object. Everything else is correct. Change it to:

    public int HealthIncrease(int health){
        //increase health
        _health += health;
        return _health;
    }
    

    You should only consider small replacement, in my opinion Player should contains Inventory, rather than vice versa. Then you will follow OOP design patterns and your code will be much better.

    high level module/class should not be dependent upon the low-level module/class

    In this case Player = high-level class and Inventory = low-level class

    both high and low-level module should not depend on details(not sure what this one means???), but abstractions(interfaces)

    Quick explanation:

    Abstractions = interface or abstract class. Quite easy to understand, it's your ICharactable interface.

    Details = implementation. It's your Inventory class. What makes your code compatible with this principle.