Your question is missing some context, for example what is the user scenario that leads to this event and what is the state you are starting from? If you were writing the BDD tests for this case, what would they look like? Knowing this would help a lot in answering your question.
How you solve the problem of relating an book to an author is domain dependent. First we are assuming it makes sense for your domain to have an aggregate for Author and an aggregate for Book, for example, if I was writing a library system, I doubt I would have an aggregate for authors, since I don t care about an author without his/her book, what I care about is books.
As for the lack of getters, it s worth mentioning that aggregate roots don t have getters because of a preference for a tell-don t-ask style of OOP. However you can tell one AR to do something which then then tells something to another AR if you need. Part of what is important is the AR tells the others about itself rather than writing code where you ask it and then pass it along.
Finally, I have to ask why you don t have the author s ID at the time you are adding the book? How would you even know who the author is then? I would assume you could just do the following (my code assumes you are using a fluent interface for creation of AR, but you can substitute factories, constructors, whatever you use):
CreateNew.Book()
.ForAuthor(command.AuthorId)
.WithContent(command.Content);
Now perhaps the scenario is you are adding a book along with a brand new author. I would either handle this as two separate commands (which may make more sense for your domain), or handle the command the following way:
var author = CreateNew.Author()
.WithName(command.AuthorName);
var book = CreateNew.Book()
.ForAuthor(author.Id)
.WithContent(command.Content);
Perhaps the problem is you have no getter on the aggregate root Id, which I don t believe is necessary or common. However, assuming Id encapsulation is important to you, or your BookAdded event needs more information about the author than the Id along can provide, then you could do something like this:
var author = CreateNew.Author()
.WithName(command.AuthorName);
var book = author.AddBook(command.Content);
// Adds a new book belonging to this Author
public Book AddBook(BookContent content) {
var book = CreateNew.Book()
.ForAuthor(this.Id)
.WithContent(command.Content);
}
Here we are telling the author to add a book, at which point it creates the aggregate root for the book and passes it s Id to the book. Then we can have the event BookAddedForAuthor which will have the id of the author.
The last one has downsides though, it creates a command that must act through multiple aggregate roots. As much as possible I would try to figure out why the first example isn t working for you.
Also, I can t stress enough how the implementation you are looking for is dictated by your specific domain context.