【问题标题】:Sharing utility objects between domain and repository在域和存储库之间共享实用程序对象
【发布时间】:2011-08-18 13:45:54
【问题描述】:

我目前正在构建一个使用MySQL 数据库的框架。我不能使用实体框架的MySQL 实现,所以我试图找出概括搜索和分页功能的最佳方法。

最简单的解决方案是使用带有以下签名的存储库方法:

IList<Blah> GetSomething(string _query, 
                         int _page, 
                         int _pageSize, 
                         out int _numPages)

但这似乎有点反OOD。

我的一个想法是创建一个带有ISearchParameterIPaging 对象的实用程序dll,域级别和存储库级别都可以访问,这将避免必须重新创建这两个接口并在每个接口中实现它们域和存储库。

public interface ISearchParameters
{
    Direction Direction { get; set; }
    string DirectionField { get; set; }
    string Query { get; set; }
    IList<string> SearchFields { get; set; }
}

public interface IPaging
{
    int CurrentPage { get; set; }
    int PageSize { get; set; }
    int NumberOfPages { get; set; }

    int GetQueryPage();
}

我通常会将 DTO 从存储库映射到域对象,但如果两个级别都引用此实用程序 .dll,那么在这两个级别之间传递 ISearchParameter 对象而不进行映射会是不好的设计吗?如果有,有没有更好的解决方案?

【问题讨论】:

    标签: c# .net design-patterns domain-driven-design repository


    【解决方案1】:
    1. 使用存储库模式抽象出您与数据访问层的交互。
    2. 使用控制反转容器来创建您的存储库,以避免从您的域引用数据访问层。
    3. 然后数据访问可以保存对您的域类或域类工厂的引用 - 避免了对 DTO 的需要(遵循 DRY 原则)。
    4. 将您的界面设计为无状态的。当跨越层(可能成为层)时,考虑服务而不是对象。这会更喜欢更简单的方法。
    5. 避免使用实用程序.dll。您实际上只需要在域和数据访问层之间共享您的存储库接口。您可以将它们放在您的域程序集中,或者更好的是,将它们放在一个单独的程序集中。

    【讨论】:

    • 嗨 afeygin,我正在构建的框架使用您在第 1、2 和 4 点中提到的原则。目前,我的数据访问工厂是自包含的,仅由存储库引用。存储库填充了 DTO,这些 DTO 映射到域层中的 BO,再映射到 MVC 站点中的模型以供视图使用。存储库真的应该推出域类吗?我认为这会在层之间产生耦合?这是一个我有很多要学习的领域,每个人似乎对什么是最好的都有自己的看法!
    • Jingo 先生:耦合和 DRY 之间存在权衡。这取决于您的应用程序。如果您的应用程序具有 SOA 架构(而且很少有),那么您必须使用 DTO。这不会是我的第一选择。不遵循 DRY 将使您的应用程序变得脆弱且难以更改,并且您希望尽可能避免它。您的域对象是系统的核心。如果您仔细设计和管理它们的生命周期,并使它们可序列化,避免持有过多的引用,它们可以作为 DTO、业务实体和 MVC 或 MVVM 模型合而为一。
    • 我猜我想说什么——是的,存储库可以推出域对象。是的,它是耦合的,但我还没有在生产系统中看到这个问题。但是,随着实体数量的增长,由于不遵循 DRY 引入的脆弱性,我已经看到无数应用程序随着时间的推移逐渐瘫痪。请记住,有意耦合并不是一件坏事。这是您需要避免的无意耦合。
    • 嗨 afeygin,感谢您抽出宝贵时间回复!我会根据你的建议玩一玩,看看效果如何。我有最后一个问题:如果域使用 IOC 创建存储库,并且存储库链接到域以生成域对象,这不会创建循环依赖关系吗?还是应该将域对象接口推送到存储库和域都引用的它们自己的 dll 中?
    • Jingo 先生:如果您的存储库接口位于与存储库实现不同的 dll 中,这将不会创建循环引用。
    【解决方案2】:

    在我看来,这是一个非常合适的解决方案。在我的项目中,我经常使用 jqGrid,当然也有搜索、排序和分页功能。我使用了一个 gridParameters 对象(在我的基础设施层中定义),它从控制器 (UI) 传递到业务层和数据层。 这些对象不包含任何业务规则,所以我认为这种方法没有任何问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-04
      • 1970-01-01
      • 2023-03-31
      相关资源
      最近更新 更多