我第一次尝试使用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; }
}
我需要一种可以通过从数据库中提取数据来填充这些集合的方法。
我很困惑我应该将这些方法放在哪个相关的Repository类中。我应该设计我的存储库,以便返回类型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) { }
}
我在这里看到的明显缺点是我需要开始实例化很多存储库。如果我的用户还分配了窗口小部件,窗口小部件和小部件怎么办?当我填充用户时,我需要实例化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) { }
}
我在这里看到的优点是,如果我现在需要我的用户拥有Widgets,Fidgets和Lidgets的集合,我只需要为UserRepository模式添加必要的方法,而不需要实例化一堆不同的存储库每次我想创建一个用户的类,但现在我已经分散了几个不同存储库中用户的顾虑。
我真的不确定哪条路是对的,如果有的话。有什么建议吗?
答案 0 :(得分:5)
存储库模式可以帮助您:
将出于同样原因改变的事情放在一起
以及
分开因不同原因而改变的事情
总的来说,我希望有一个&#34; User Repository&#34;成为获取用户的存储库。理想情况下,它将是您可以用来获取用户的唯一存储库,因为如果您更改了用户表或用户域模型等内容,则只需要更改用户存储库。如果您在许多存储库中拥有用于获取用户的方法,则他们都需要更改。
限制变革的影响是好的,因为变革是不可避免的。
至于实例化许多存储库,使用依赖注入工具(如Ninject或Unity)来提供存储库或使用存储库工厂,可以减少大量存储库的使用。
最后,您可以了解域驱动设计的概念,以了解有关域模型和存储库背后的主要目的的更多信息(以及与您正在执行的操作相关的聚合根)。
答案 1 :(得分:1)
没有正确答案的引人入胜的问题。这可能更适合programmers.stackexchange.com而不是stackoverflow.com。以下是我的想法:
不要担心创建太多的存储库。它们基本上是无状态对象,因此不会使用太多内存。即使在你的例子中,它也不应该成为程序员的重大负担。
存储库的真正好处是模拟存储库以进行单元测试。考虑根据单元测试最简单的方法将它们拆分,以使依赖注入变得简单明了。我已经看到每个查询都是存储库的情况(他们称之为&#34;查询&#34;而不是存储库)。在其他情况下,一切都有一个存储库。
答案 2 :(得分:0)
事实证明,在这种情况下,第一个选项是更实用的选项。这有几个原因:
1)当对类型及其关联的存储库(假设Ticket)进行更改时,远更容易在一个地方修改Ticket和TicketRepository,而不是追逐每个存储库中的每个方法。使用了票。
2)当我尝试使用接口来指示每个存储库可以提取的队列类型时,我遇到了一个问题,即单个存储库无法多次使用类型T实现通用接口,而接口方法实现中只有区别是参数类型。
3)我在我的实现中访问SharePoint和数据库中的数据,并创建了两个抽象类,为Sharepoint或SQL Server的具体存储库提供数据工具。假设在上面的示例中,用户来自Sharepoint,而票证来自数据库。使用我的模型我将无法使用这些抽象类,因为该组必须从我的Sharepoint抽象类和我的SQL抽象类继承。 C#不支持抽象类的多重继承。但是,如果我将所有与Ticket相关的行为分组到TicketRepository中,并将所有与用户相关的行为分组到UserRepository中,则每个存储库只需要访问一种类型的底层数据源(分别是SQL或Sharepoint)。