Search code examples
c#oopencapsulation

Accessing root class encapsulated properties within an object graph


I am currently writing an Adventure Game Creator Framework and I have the following classes so far:

// Base class that represents a single episode from a complete game.
public abstract class Episode : IEpisode
{
    public RoomList Rooms {get; }
    public ArtefactList Artefacts {get; }

    public Episode()
    {
        Rooms = new RoomList();
        Artefacts = new ArtefactList();
    }
}

// This is a list of all objects in the episode.
public ArtefactList : List<IArtefact>
{
    public IArtefact Create( UInt32 id, String text )
    {
        IArtefact art = new Artefact( id, text );

        base.Add( art );

        return art;
    }
}

// This is a list of all rooms in the episode.
public RoomList : List<IRoom> 
{   
    public IRoom Create( UInt32 id, String text )
    {
        IRoom rm = new Room( id, text );

        base.Add( rm );

        return rm;
    }
}

public class Room : IRoom
{
    public UInt32 Id { get; set; }
    public String Text { get; set; }

    public IList<IArtefact> Artefacts
    {
        get
        {
            return ???what??? // How do I access the Artefacts property from
                                // the base class:
                                //  (Room --> RoomList --> Episode)
        }
    }   
}

public class Artefact : IArtefact
{
    public UInt32 Id { get; set; }
    public String Text { get; set; }
    public IRoom CurrentRoom { get; set; }

}

public interface IArtefact
{
    UInt32 Id { get; set; }
    String Text { get; set; }
    IRoom CurrentRoom { get; set; }
}

public interface IRoom
{
    UInt32 Id { get; set; }
    String Text { get; set; }
    IList<IArtefact> Artefacts {get; }
}

What I'd like to know is how the Room class should access the encapsulated Artefacts property of the Episode class without having to pass a reference to Episode all the way down the object graph, i.e. Episode --> RoomsList --> Room.


Solution

  • There's a one-to-many relationship between room and artefact. Therefore, you must initialize this relationship in the RoomList.Create method:

    public IRoom Create( UInt32 id, String text , ArtefactList artefacts)
    {
        IRoom rm = new Room( id, text , artefacts);
        base.Add( rm );
        return rm;
    }
    

    And when creating a room, you can do like so:

    var episode = new Episode();
    episode.Rooms.Create(1, "RoomText", episode.Artefacts);
    

    You should do the same for ArtefactList.Create as Artefact requires IRoom instance.