Doing a bit of reading around domain driven design and it seems that you're supposed to access all entities within an aggregate by traversal from the aggregate root.
However, at the same time you should really try and encapsulate your data so that the properties/fields are protected or private.
Therefore my question is: If the fields are protected/private how are you supposed to traverse the aggregate?
The way I have set it up at the moment is as follows: I mark all the properties of my domain model as internal with the methods for "setting" marked as protected. This way, at least nothing outside the model can access the properties, but objects within the model can access other objects properties and I still only allow setting of the properties from within the object itself.
Even though I've done this, I still feel as if this should only apply for properties for other aggregate entities (I mean, a Customer's "name" would still be private, but their "Orders" should be marked as internal to allow for the traversal from Customer -> Orders -> etc.)
Does anyone have any guidance on this?
EDIT:
Let me try and give a more concrete example for the question: I have a two objects in my object graph: Bookshelf and Book. Let us say for the sake of this example that Bookshelf is the aggregate root, and that Books are stored on a bookshelf so are just entities within the aggregate (Bookshelf has a collection of books).
I want to write a method to add a new book to the bookshelf. Following DDD best practices, I believe I should write a method on the Bookshelf class such as AddBook(Book book).
However, what if there is a business requirement that no book with the same title can be added to the bookshelf. I want some logic within the Bookshelf.AddBook method to check the collection of books to make sure this book doesn't already exist.
The problem now is that I can't do that as I've written the Book object in a nicely encapsulated way and its "Name" property is not publicly accessible.
I understand this is a fairly contrived example, but I hope that it better illustrates the problem. I also now realise that this isn't just a DDD problem, but an OO encapsulation one in reality. I'm sure that there must be a very common, easy way of solving what I'm trying to do and I'm massively overthinking it.