对IRepository的困惑

时间:2010-09-12 21:12:53

标签: c# mvvm entity-framework-4 repository-pattern

在实际加载数据时,我对使用“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方法抽象功能是有意义的。但在这种情况下,或许使用一些查询对象会更理想吗?

3 个答案:

答案 0 :(得分:2)

我有点困惑的是你的上下文已经到了你的ViewModel。我相信您的GUI图层永远不会看到上下文。必须由IRepository打开/保持/关闭上下文。让数据层(IRepository)返回Users的数组/列表。

答案 1 :(得分:2)

这里有几点不同。首先,您的视图模型应该不了解存储库 - 让您的视图模型尽可能简单。

其次,IRepository是你的公共API - 所以你应该依赖于它(取决于抽象而不是层之间的具体实现)。

实现IRepository有几种不同的(完全可以接受的方式)。一种是让存储库直接封装上下文。另一种方法是使用“工作单元”模式,让unitOfWork封装上下文并将unitOfWork对象传递给每个存储库。无论哪种方式,因为您使用EF4,可测试性比以前容易得多。例如,EF4引入了IObjectSet,因此很容易提供测试双打和模拟来测试您的存储库。

我强烈建议您在Testability and Entity Framework 4上查看此白皮书。

答案 2 :(得分:1)

Separation of concerns

如果要更改“用户”的存储空间,例如从SQL更改为平面文件,该怎么办?

然后不需要context,您必须更改它的每次使用,而不仅仅是IRepository实施。

另外,理想情况下,你会注射IRepository。所以你MainViewModel并不关心它是如何得到的Users