C# Repository Pattern – Effective Placement of Methods

cdesign-patternsrepository

I'm trying to build a new application using the Repository pattern for the first time and I'm a little confused about using a Repository. Suppose I have the following classes:

public class Ticket
{

}
public class User
{
   public List<Ticket>AssignedTickets { get; set; }
}
public class Group
{
   public List<User> GroupMembers { get;set; }
   public List<Ticket> GroupAssignedTickets { get;set; }
}

I need methods that can populate these collections by fetching data from the database.

I'm confused as to which associated Repository class I should put those methods in. Should I design my repositories so that everything returning type T goes in the repository for type T as such?

public class TicketRepository
{
   public List<Ticket> GetTicketsForGroup(Group g) { }
   public List<Ticket> GetTicketsForUser(User u) { }
}
public class UserRepository
{
  public List<User> GetMembersForGroup(Group g) { }
}

The obvious drawback I see here is that I need to start instantiating a lot of repositories. What if my User also has assigned Widgets, Fidgets, and Lidgets? When I populate a User, I need to instantiate a WidgetRepository, a FidgetRepository, and a LidgetRepository all to populate a single user.

Alternatively, do I construct my repository so that everything requesting based on type T is lumped into the repository for type T as listed below?

public class GroupRepository
{
    public List<Ticket> GetTickets(Group g) { }
    public List<User> GetMembers(Group g) { }
}
public class UserRepository
{
   public List<Ticket> GetTickets(User u) { }
}

The advantage I see here is that if I now need my user to have a collection of Widgets, Fidgets, and Lidgets, I just add the necessary methods to the UserRepository pattern and don't need to instantiate a WidgetRepository, FidgetRepository, and LigetRepository class every time I want to create a user, but now I've scattered the concerns for a user across several different repositories.

I'm really not sure which way is right, if any. Any suggestions?

Best Answer

The second option seems like you are defining your repository based on your requirements for this given application vs 1 repository per "table" which could be more flexible for other areas of your app that might come up or other applications that might not group stuff like your current app does. Yes, it means you'll have a fair amount of repositories, but then they are reusable inside any project that needs access to said repository.

I generally make repositories per "table" (I work in DB mostly) and then make "service" classes (some say UnitofWork I think) that group repositories and has an interface to give functionality to that service.