From my experience I think that having classes/models without behaviour only in my application, next to their repositories is not good OOP. But, this was the way I implemented the repository pattern. I just make everywhere I need an repository instance, to perform some actions. The result of this approach was that all my domain classes didn't have behaviour.
They were just objects holding data with no methods. My teacher said to me that I was using thin models and that I should strive to make fat models. In response to that feedback, I implemented some business logic in the classes, but I ran into some problems:
Example:
public class Movie
{
private MovieRepository movieRepo = new MovieRepository(new MovieDbContext());
private PostRepository postRepo = new PostRepository(new PostDbContext());
public decimal Rating { get; set; }
public List<Post> Posts { get; set; }
public void Rate(User user, Movie movie)
{
if(movie.Rating < 0 || movie.Rating > 10)
{
throw new Exception("The rating must be a digit between 0 and 10");
}
this.Rating = movie.Rating;
movieRepo.RateMovie(user.Id, movie.Id, (int)movie.Rating);
}
public void AddPost(User user, Movie movie, string text)
{
int maxId = 0;
foreach (Post p in Posts)
{
if (p.Id > maxId)
{
maxId = p.Id;
}
}
Post post = new Post(maxId + 1, user, text, DateTime.Now);
this.Posts.Add(post);
postRepo.AddPost(user.Id, movie.Id, text, DateTime.Now);
}
}
As you can see in the example above, I first handle some domain logic, to perform actions on the class itself and then I persist it to the database using a repository. But why am I even adding the posts to the class itself in the AddPost-method, when I handle it with a repository right after?
Is this just because you can now actually see the changes you made directly on the screen, in-memory? Or is business logic's purpose only to validate parameter's input, as shown in the movie Rate method? But these kind of exceptions can also be thrown in the repository if the repository method also checks if a digit is between 0 and 10. But i think a repository shouldn't be concerned about that. The repository only needs to translate input to database information, am I right?
But having said that, I don't understand exactly the need of performing changes on the object itself, when you handle it with a repository. Instead of that you could to this(anywhere in your application, to display the user object):
postRepo.AddPost(2, 1, "Nice movie!", DateTime.Now);
User user = userRepo.GetById(2);
What are the pros and cons of this difference?