【问题标题】:MVC3, RavenDB, AutoMapper, IoC/DI and Geese - where should I use my associated repositories?MVC3、RavenDB、AutoMapper、IoC/DI 和 Geese - 我应该在哪里使用我的关联存储库?
【发布时间】:2011-11-10 05:33:00
【问题描述】:

我对 RavenDB 和 MVC3 非常陌生,尤其是 IoC 的用法(不是概念)。所以只是警告你,这听起来像是一个非常初学者的问题。

总结: 我有一个域模型,假设它是

public class Goose

在这个类中,我可能有一个更复杂的对象作为属性

    public Beak beak { get; set; }

在 RavenDB 中,我们被正确地鼓励 [JsonIgnore] 这个属性或者根本没有它,而是有一个引用标识符,比如

    public String beakId { get; set; }

在我的 MVC3 应用程序中的某个地方,我想查看 Goose,我可能想向用户显示一些关于 Goose 和它的喙(应该是 Bill 吗?)的信息。所以是的,我需要一个视图模型,对吗?

public class GooseModel
{
    public String BeakColour { get; set; }
    public String BeakLength { get; set; }
    ...etc
}

好吧,假设我有一些 GooseRepository 和一些 BeakRepository,这是一个简单的问题......

我在 GooseController 类中,我正在加载一个 Goose 来查看。我在什么时候使用 BeakRepository,谁应该知道它? GooseController 知道 GooseRepository 并通过 id 加载 Goose。在这一点上,我们可以在 Goose 类中拥有一些代表整个 Beak 的属性,但我真的不想将 BeakRepository 注入 GooseRepository 吗?好的,所以也许当我从 Goose 创建 GooseModel 时,我发现我可以获得 BeakColour 和 BeakLength 的 GooseModel 属性,如何?好吧,我喜欢 AutoMapper,所以也许我的 Goose 的 GooseModel 地图正在使用 BeakRepository 来查找 Beak,然后提取两个 Beak 属性来填充 GooseModel 字段。这似乎也是错误的……所以还剩下什么? GooseController.. Goose 控制器是否应该知道 BeakRespository,然后找到并设置 BeakColour 和 BeakLength!?这当然看起来也完全错误..

那么它在哪里完成呢?控制器、域对象、映射器还是其他地方?也许我应该有一个在 Goose 视图中使用的 Type Beak 的部分视图?..

【问题讨论】:

  • 我实际上认为,在 Raven 中,您可能希望 Beak 成为鹅的复杂对象/属性,而不是单独的文档。一般来说,当涉及到文档数据库时,这类事情的例子非常非常糟糕。

标签: asp.net-mvc-3 architecture ravendb


【解决方案1】:

我倾向于将这种逻辑整合到服务/业务层 (GooseService) 中,然后将其注入控制器。您的服务层可能采用GooseRepositoryBeakRepository,并返回已将GooseViewModel 映射在一起的已解析对象。

【讨论】:

  • 啊,所以 GooseService 将承担生成/映射 GooseModel 的责任?我想这里会有某种类型的解析器负责提供 GooseService?
  • 正确。根据您的喜好,您只需选择一个 ioc 容器并将其连接起来。您需要为您选择的 ioc 容器创建一个自定义的 DependencyResolver,因为这就是您的控制器的构建方式。我默认使用结构映射,但 ninject 很好,而且我听说过有关新版本统一的好消息。
  • 谢谢!我一直在研究这些并从 StructureMap 开始,但我必须说我正在努力寻找一个带有 MVC3 的简单 IoC 示例,该示例使用 StructureMap 并明确定义了放置什么的位置。我可以看到代码将如何执行和运行 UT,但不清楚如何在 asax 应用程序启动中连接它
  • 这是一个从头到尾的结构图 mvc3。这是一个体面的实施。 stevesmithblog.com/blog/…
【解决方案2】:

嗯,...阅读您的问题,我强烈建议您忘记服务层和存储库层。如果您没有很好的理由保留它们(测试不是其中之一,因为 RavenDB 有一个 EmbeddableDocumentStore,它既快速又简单)拉动它们以利用 RavenDB 的一些非常好的特性。

我实际上写过一篇文章,说明为什么我认为您通常应该避免这些层: http://daniellang.net/keep-your-code-simple/ 这是关于 NHibernate,但概念也适用于此。

您是否应该将 BeakColor 和 BeakLength 属性非规范化到您的 Goose 文档中取决于您的应用程序需要。如果您对术语“聚合根”感到满意,那么经验法则是这些通常是您的文档。如果您不确定是否应该应用非规范化,请避免使用它,并在加载 Goose 时使用 .Include(goose => goose.Beak)

如果这对你有意义,请告诉我。

【讨论】:

  • 在编程中从来没有真正“正确”的做事方式,我对 MVC3 的不同方法的数量感到相当沮丧。话虽如此,您关于取消存储库层的建议很有趣。我目前正在尝试学习最佳实践,因此“需要”并不是一个真正的因素。我想我仍然可以使用存储库并在从 Raven 检索时要求它包含 Beak,然后从 beakId 填充非序列化对象属性。我在正确的轨道上吗?
  • 哈!我读过你的文章,非常非常好的观点。我的职业生涯始于使用 ADO 的经典 ASP 内联 SQL,我得说我可以很快完成工作。当然,我从中成长并使用了很多 VB/C++ COM 的东西和后来的 .Net。但每次我从最近的事情开始时,我都会有一种下沉的感觉。那里有一些很棒的想法,但它们不必一次全部使用..
  • 很高兴听到您喜欢这个主意。至于填充 Goose 对象,我不确定我是否理解您的问题。查看 RaccoonBlog 示例 (github.com/ayende/RaccoonBlog) 可能会对您有所帮助。如果没有,你也可以给我发电子邮件。
猜你喜欢
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多