在 ASP.NET MVC 中使用存储库模式和 SQL Server DB;如何模拟存储库,使其可以在不破坏 OOD 的情况下进行单元测试

发布于 2024-09-09 10:28:59 字数 554 浏览 4 评论 0原文

我一直在使用 Steven Sanderson 所著的 Apress 书籍“Pro ASP.NET MVC Framework”来学习 ASP.NET MVC 框架。为此,我一直在一个我不太熟悉但我应该做的项目上尝试一些事情,即:

  • 使用存储库模式来访问我的数据库并填充我的域/业务对象。
  • 使用存储库的接口,以便可以在测试项目中对其进行模拟。
  • 使用控制反转创建我的控制器

我有一个 MVC Web 应用程序、域库、测试库。

在我的数据库中,我的域项目有一个 Id,表示为 int 标识列。在我的域类中,设置器是内部的,因此只有存储库可以设置它。

所以我的困惑/问题是:

  1. 实际上域库中的所有类都可以设置 Id 属性,这对 OOP 不利,因为它们应该是只读的。
  2. 在我的测试库中,我创建了一个假存储库。但是,由于它是不同的程序集,我无法在类上设置 Id 属性。

其他人在使用数据库数据存储时会做什么?我想许多人使用整数 Id 作为数据库中的唯一标识符,然后需要将其设置为对象,而不是通过其他任何东西。

I've been learning the ASP.NET MVC framework using the Apress book "Pro ASP.NET MVC Framework" by Steven Sanderson. To that end I have been trying out a few things on a project that I am not that familar with but are things that I thing I should be doing, namely:

  • Using repository pattern to access my database and populate my domain/business objects.
  • Use an interface for the repository so it can be mocked in a test project.
  • Use inversion of control to create my controllers

I have an MVC web app, domain library, test library.

In my database my domain items have an Id represented as an int identity column. In my domain classes the setter is internal so only the repository can set it.

So my quandries/problems are:

  1. Effectively all classes in the domain library can set the Id property, not good for OOP as they should be read-only.
  2. In my test library I create a fake repository. However since it's a different assembly I can't set the Id properties on classes.

What do others do when using a database data store? I imagine that many use an integer Id as unique identifier in the database and would then need to set it the object but not by anything else.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

聊慰 2024-09-16 10:28:59

不能在构造期间设置对象的 ID 并将其设置为只读,而不是通过 setter 方法设置 ID 吗?

或者其他时候需要设置ID吗?如果是这样,你能解释一下为什么吗?

编辑:

是否可以将 ID 和域对象分开?除了存储库之外,还有其他东西需要知道 ID 吗?

从域对象中删除 ID 字段,并让存储库实现使用私有字典跟踪对象 ID。这样任何人都可以创建域对象的实例,但他们不能使用 ID 做愚蠢的事情。

这样,域对象的 ID 就是存储库实现决定的任何内容 - 它们可以是来自数据库、url 或文件名的整数。

如果有人在存储库外部创建了一个新的域对象,并尝试将其保存到您的存储库中,您可以查找该对象的 ID 并根据需要进行保存。如果 ID 不存在,您可以抛出异常,表明您需要使用存储库方法创建对象,或者为其创建一个新 ID。

有什么会阻止您使用这种模式吗?

Can't you set your objects' IDs during construction and make them read-only, rather than setting IDs through a setter method?

Or do you need to set the ID at other times. If that's the case, could you explain why?

EDIT:

Would it be possible to divorce the ID and the domain object? Does anything other than the repository need to know the ID?

Remove the ID field from your domain object, and have your repository implementations track object IDs using a private Dictionary. That way anyone can create instances of your domain objects, but they can't do silly things with the IDs.

That way, the IDs of the domain objects are whatever the repository implementation decides they are - they could be ints from a database, urls, or file names.

If someone creates a new domain object outside of the repository and say, tried to save it to your repository, you can look up the ID of the object and save it as appropriate. If the ID isn't there, you can either throw an exception to say you need to create the object using a repository method, or create a new ID for it.

Is there anything that would stop you from using this pattern?

左耳近心 2024-09-16 10:28:59

您可以使用 InternalsVisibleTo 属性。它将允许程序集中的类型在测试中可见(前提是它们位于不同的程序集中)。

否则,您可以将该属性保留为外部对象的只读属性,但同时拥有一个具有 ID 参数并设置 ID 属性的构造函数。然后你可以调用该构造函数。

希望这有帮助。

you can use the InternalsVisibleTo attribute. It will allow the types from an assembly to be visible from the tests (provided they are in different assemblies).

Otherwise you can leave the property read-only for the external objects but in the same time have a constructor which has an ID parameter and sets the ID property. Then you can call that constructor.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文