views:

232

answers:

1

So lets say I have a class called Post that contains an IList

I find that it's quite easy to cope with adding of Comments to the list when I ask my repository to update my post it can see which comments are new and send down to my data layer the required information, but what about when a comment is deleted? How do you handle this?

Would you pull back a list of comments to check which ones no longer exist in the current changed collection?

Or wire up events to keep track of it?

or something else entirely?

Just for further information, I'm doing this in C# and can't use a O/R Mapper. I have to use stored procedures to retrieve datasets and map my objects manually. I may have my understanding of the repository pattern wrong, but I am using it to mediate to the data layer, from requesting data, adding data and such, and it maps my dataset data to objects and returns the object(s). So feel free to elaborate on how to use the Repository pattern as well if you wish.

A: 

If I understand what you are attempting, you are adding a Comment() to the IList in question which is attached to a Post(). And within your Post(), you are looking for any new Comment()s in the IList and saving them. Having the Post() object control its child objects, such as Comment()s, does go down the road of DDD.

I am still new to these patterns myself; but personally, I lean towards the concept that any entity that has metadata, I treat as its own entity model; therefore, I create my own repostiory for each entity model.

Post()
PostRepository : IPostRepository

Comment()
CommentRepository : ICommentRepository

Now, having a IList Post.Comments I believe violates the Law of Demeter by allowing you to execute Post.Comments.Add().

I believe a solution to your problem would be not add to the IList, but instead create methods on the Post() to handle the comments related to that Post instance:

Post.AddComment()
Post.FetchComments()
Post.DeleteComments(IList<Comment> comments)

Then within your Post() object, you would wire up your ICommentRepository (most likely with a ServiceLocator, or I prefer Castle Windsor) and handle adding and deletion of them.

ICommentRepository.AddByPostID()
ICommentRepository.FetchByPostID()
ICommentRepository.Remove(int commentID)

Again, I am still new to the DDD patterns; but, I believe this is keeps the Seperation of Concerns valid and masks the underlying logic by keeping it within the Post()'s concern to "only handle actions on comments related to this Post object".

The complete Post() class would be something like this:

private ICommentRepository _commentRepo;

public class Post
{
  public Post(ICommentRepository commentRepo)
  {
    // Or you can remove this forced-injection and use a 
    // "Service Locator" to wire it up internall.
    _commentRepo = commentRepo;
  }

  public int PostID { get; set; }

  public void DeleteComments(IList<Comment> comments)
  {
    // put your logic here to "lookup what has been deleted"
    // and then call ICommentRepository.Delete() in the loop.

    _commentRepo.Remove(commentID);
  }
}

Please comment if others have opinions or changes.

eduncan911
Aye, but what I don't like here is that now the post has the responsibility of updating the comment repository, which is beyond the scope of just being a post.
Sekhat
If anything the post repository (dealing with keeping track of posts) should also update the comment repository with changes when a post is asked to be saved / updated.
Sekhat
I vision it as, "A Comment() cannot exist without a Post() container." Therefore, I believe it is ok for the post to abstract the inner workings of a Comment() object; along while, your backend continues to support SoC by having a seperate ICommentRepository.
eduncan911