C#中的有效存储库-将方法放在何处?

C#中的有效存储库-将方法放在何处?,c#,design-patterns,repository,C#,Design Patterns,Repository,我第一次尝试使用Repository模式构建一个新的应用程序,但我对使用Repository有点困惑。假设我有以下几个类: public class Ticket { } public class User { public List<Ticket>AssignedTickets { get; set; } } public class Group { public List<User> GroupMembers { get;set; } public

我第一次尝试使用Repository模式构建一个新的应用程序,但我对使用Repository有点困惑。假设我有以下几个类:

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; }
}
公共舱票
{
}
公共类用户
{
公共ListAssignedTickets{get;set;}
}
公共课组
{
公共列表组成员{get;set;}
公共列表GroupAssignedTickets{get;set;}
}
我需要一个方法,可以通过从数据库获取数据来填充这些集合

我不知道应该将这些方法放在哪个相关的存储库类中。我是否应该设计我的存储库,使返回类型T的所有内容都进入类型T的存储库

public class TicketRepository
{
   public List<Ticket> GetTicketsForGroup(Group g) { }
   public List<Ticket> GetTicketsForUser(User u) { }
}
public class UserRepository
{
  public List<User> GetMembersForGroup(Group g) { }
}
public class TicketRepository
{
公共列表GetTicketsForGroup(组g){}
公共列表getticketsfourser(用户u){}
}
公共类用户存储库
{
公共列表GetMembersForGroup(组g){}
}
我在这里看到的明显缺点是,我需要开始实例化许多存储库。如果我的用户还分配了widget、fidget和lidget呢?在填充用户时,我需要实例化WidgetRepository、FidgetRepository和LidgetRepository来填充单个用户

或者,我是否构建我的存储库,以便将基于类型T的所有请求都集中到类型T的存储库中,如下所示

public class GroupRepository
{
    public List<Ticket> GetTickets(Group g) { }
    public List<User> GetMembers(Group g) { }
}
public class UserRepository
{
   public List<Ticket> GetTickets(User u) { }
}
公共类组存储库
{
公共列表GetTickets(g组){}
公共列表GetMembers(组g){}
}
公共类用户存储库
{
公共列表GetTickets(用户u){}
}
我在这里看到的优点是,如果我现在需要我的用户拥有一个widget、fidget和lidget的集合,我只需向UserRepository模式添加必要的方法,而不需要每次创建用户时都实例化一堆不同的存储库类,但是现在我已经将用户的关注分散到了几个不同的存储库中


我真的不知道哪条路是对的,如果有的话。有什么建议吗?

有趣的问题,没有正确的答案。这可能更适合程序员使用。stackexchange.com而不是stackoverflow.com。以下是我的想法:

不要担心创建太多的存储库。它们基本上是无状态对象,因此不会占用太多内存。即使在您的示例中,它也不应该成为程序员的重大负担


存储库的真正好处是模拟存储库进行单元测试。考虑基于单元测试中最简单的方法将它们拆分,以使依赖性注入变得简单明了。我见过这样的情况:每个查询都是一个存储库(他们称这些“查询”而不是存储库)。以及其他所有内容都有一个存储库的情况。

存储库模式可以帮助您:

把因同样原因而改变的事情放在一起

以及

将因不同原因而改变的事物分开

总的来说,我希望“用户存储库”是获取用户的存储库。理想情况下,它将是您可以用来获取用户的唯一存储库,因为如果您更改内容,如用户表或用户域模型,您只需要更改用户存储库。如果您在许多存储库中有获取用户的方法,那么它们都需要更改

限制变革的影响是好的,因为变革是不可避免的

至于实例化许多存储库,使用依赖项注入工具(如Ninject或Unity)来提供存储库,或者使用存储库工厂,可以减少创建大量存储库的工作量


最后,您可以查看域驱动设计的概念,以了解更多关于域模型和存储库背后的关键用途(以及与您所做工作相关的聚合根)。

事实证明,在这种情况下,第一个选项是更实用的选项。这有几个原因:

1) 在对类型及其关联的存储库(假设为Ticket)进行更改时,在一个位置修改Ticket和ticketpositionory要比在每个使用Ticket的存储库中查找每个方法容易得多

2) 当我尝试使用接口来指定每个存储库可以拉入的队列类型时,我遇到了一个问题,即单个存储库无法多次使用类型t实现通用接口,接口方法实现中唯一的区别是参数类型


3) 我从SharePoint和实现中的数据库访问数据,并创建了两个抽象类,为SharePoint或SQL Server的具体存储库提供数据工具。假设在上述示例中,用户来自Sharepoint,而票证来自数据库。使用我的模型,我将无法使用这些抽象类,因为该组必须从我的Sharepoint抽象类和SQL抽象类继承。C#不支持抽象类的多重继承。但是,如果我将所有与票证相关的行为分组到票证存储库中,将所有与用户相关的行为分组到用户存储库中,则每个存储库只需要访问一种类型的基础数据源(分别为SQL或Sharepoint)。

“这可能更适合程序员。stackexchange.com而不是stackoverflow.com。”…虽然它是我最喜欢的标签之一,但您所说的可能适用于整个
设计模式
标签。我一直很惊讶整个团队还没有搬迁。设计模式问题几乎总是主观的。