在实际加载数据时,我对使用“IRepository模式”时有点困惑。
目前我有这样的事情:
public class MainViewModel : ViewModelBase
{
// EF4 generated ObjectContext
private ScorBotEntities context = new ScorBotEntities();
// Custom IUserRepository class
private IUserRepository userRepository;
public MainViewModel()
{
this.userRepository = new UserRepository(context.Users);
}
public ObservableCollection<User> Users
{
get
{
return new ObservableCollection<User>(userRepository.GetAll());
}
}
}
使用EF4自动生成ScorBotEntities(我看了一下POCO,为这个大小的项目做了很多工作)。
您可以在此处找到UserRepository的定义:http://code.google.com/p/i4prj4-g2/source/browse/ScorBotRobotics/ScorBotRobotics/Repositories/UserRepository.cs
但基本上,我想知道的是,为什么在这里使用存储库甚至是有意义的,而不是像这样写:
public class MainViewModel : ViewModelBase
{
private ScorBotEntities context = new ScorBotEntities();
public MainViewModel()
{
}
public ObservableCollection<User> Users
{
get
{
return new ObservableCollection<User>(context.Users);
}
}
}
使用UsernameAndPassword方法抽象功能是有意义的。但在这种情况下,或许使用一些查询对象会更理想吗?
答案 0 :(得分:2)
我有点困惑的是你的上下文已经到了你的ViewModel。我相信您的GUI图层永远不会看到上下文。必须由IRepository
打开/保持/关闭上下文。让数据层(IRepository
)返回Users
的数组/列表。
答案 1 :(得分:2)
这里有几点不同。首先,您的视图模型应该不了解存储库 - 让您的视图模型尽可能简单。
其次,IRepository是你的公共API - 所以你应该依赖于它(取决于抽象而不是层之间的具体实现)。
实现IRepository有几种不同的(完全可以接受的方式)。一种是让存储库直接封装上下文。另一种方法是使用“工作单元”模式,让unitOfWork封装上下文并将unitOfWork对象传递给每个存储库。无论哪种方式,因为您使用EF4,可测试性比以前容易得多。例如,EF4引入了IObjectSet,因此很容易提供测试双打和模拟来测试您的存储库。
我强烈建议您在Testability and Entity Framework 4上查看此白皮书。
答案 2 :(得分:1)
如果要更改“用户”的存储空间,例如从SQL更改为平面文件,该怎么办?
然后不需要context
,您必须更改它的每次使用,而不仅仅是IRepository
实施。
另外,理想情况下,你会注射IRepository
。所以你MainViewModel
并不关心它是如何得到的Users
。