Wadjey
Wadjey

Reputation: 165

C# Loose coupling to access to a property value

I want to create loosely coupled classes (PlayerProfile and PlayersManager) and be able to access the value of the PlayerScore property (that's implemented in PlayerProfile) from PlayersManager(without knowing about PlayerProfile)

public class PlayerProfile : IPlayer
{
    int myScore = 520;

    public int PlayerScore
    {
        get
        {
            return myScore;
        }
    }
}



public interface IPlayer
{
    int PlayerScore { get; }
}



public class PlayersManager
{
    //There is any way to access here to the value of "PlayerScore" without creating an instance
    //of PlayerProfile and without depending in any way of the PlayerProfile (like IClass myClass = new PlayerProfile())?
}

PS: I don't know if using interfaces is the right way to do it or if there is another way.

Any idea how I can achieve this? Thanks

Upvotes: 1

Views: 376

Answers (2)

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112372

You can use constructor injection. This is a Dependency Injection Design Pattern. See also: Dependency injection.

public class PlayersManager
{
    private readonly IPlayer _player;

    PlayersManager(IPlayer player)
    {
        _player = player;
    }

    public void Manage() // Example
    {
        int score = _player.PlayerScore;
        ...
    }
}

Dependency injection frameworks can create and inject the dependency automatically. They work like this (of course the details vary among the different dependency injection frameworks):

Create a dependency injection container in a static class

public static class DI
{
    public static SomeContainer Container { get; } = new SomeContainer();
}

At program startup register your services

DI.Container.Register<IPlayer, PlayerProfile>();
DI.Container.Register<PlayersManager>();

Then create a PlayersManager with:

// This automatically creates a `PlayerProfile` object and a `PlayersManager` object by
// injecting the player profile into the constructor of the manager.
var pm = DI.Container.Resolve<PlayersManager>();

It does the same as

IPlayer temp = new PlayerProfile();
var pm = new PlayersManager(temp);

Upvotes: 0

vc 74
vc 74

Reputation: 38179

To detail my comment:

public interface IClass
{
     int PlayerScore { get; }
}

public class ClassA : IClass
{
    public int PlayerScore { get; } = 250;
}

public class ClassB
{
    public ClassB(IClass aClass)
    {
        _aClass = aClass;
        // Now you can use _aClass.PlayerScore in the other methods
    }
    private readonly IClass _aClass;
}

Now after reading your updated code:

public interface IPlayerProfile
{
     int PlayerScore { get; }
}

public class Player : IPlayerProfile
{
    public int PlayerScore { get; } = 250;
}

public class PlayersManager
{
    public Add(IPlayerProfile profile)
    {
        // Use profile.PlayerScore
    }
}

Upvotes: 1

Related Questions