恢复域对象的最佳方法

2024-03-21

这是一个如此简单而常见的场景,我想知道到目前为止我是如何做到的以及为什么现在遇到问题。

我有这个对象(基础设施程序集的一部分)

public class Queue {}

public class QueueItem
{
    public QueueItem(int blogId,string name,Type command,object data)
    {
        if (name == null) throw new ArgumentNullException("name");
        if (command == null) throw new ArgumentNullException("command");
        BlogId = blogId;
        CommandType = command;
        ParamValue = data;
        CommandName = name;
        AddedOn = DateTime.UtcNow;
    }


    public Guid Id { get; internal set; }
    public int BlogId { get; private set; }
    public string CommandName { get; set; }
    public Type CommandType { get; private set; }
    public object ParamValue { get; private set; }
    public DateTime AddedOn { get; private set; }
    public DateTime? ExecutedOn { get; private set; }
    public void ExecuteIn(ILifetimeScope ioc)
    {
        throw new NotImplementedException();
    }
}

这将在另一个程序集中创建,如下所示

 var qi = new QueueItem(1,"myname",typeof(MyCommand),null);

这里没有什么不寻常的。然而,这个对象将被发送到它将被持久化的存储库。Queue对象将向存储库询问项目。存储库应该重新创建 QueueItem 对象。

但是,如您所见,QueueItem 属性是不变的,AddedOn属性只能在创建项目时设置一次。这Id属性将由队列对象设置(这并不重要)。

问题是我应该如何在存储库中重新创建 QueueItem?我可以有另一个构造函数,它需要所有属性的每个值,但我不希望该构造函数可用于最初创建队列项的程序集。该存储库是不同程序集的一部分,因此内部无法工作。

我考虑过提供一个工厂方法 队列项目类 { /* ..其余定义.. */

     public static QueueItem Restore(/* list of params*/){}
   }

这至少明确了意图,但我不知道为什么我不喜欢这种方法。我还可以仅通过 Queue 强制创建项目,但这意味着将 Queue 作为对存储库的依赖项传递,这又不是我想要的。为此拥有一个特定的工厂对象似乎也有点矫枉过正。

基本上我的问题是:在存储库中重新创建对象的最佳方法是什么,不暴露特定的创建功能到另一个消费者对象.

Update

值得注意的是,我所说的存储库是指模式本身作为一种抽象,而不是 ORM 的包装器。域对象的持久化方式和位置并不重要。存储库如何重新创建很重要。另一件重要的事情是我的领域模型 是不同的来自持久化模型。我确实使用 RDBMS,但我认为这只是一个实现细节,不应该具有任何重要性,因为我正在寻找不依赖于特定存储访问的方法。

虽然这是一个特定的场景,但它基本上可以应用于存储库将恢复的每个对象。

Update2

好吧,我不知道我怎么能忘记 AutoMapper。我的错误印象是它无法映射私有字段/设置器,但它可以,而且我认为这是最好的解决方案。

事实上,我可以说最佳解决方案(IMO)是有序的:

  1. 直接反序列化(如果可用)。
  2. Automap.
  3. 域对象本身的工厂方法。

前两个不需要对象做任何特别的事情,而第三个需要对象提供针对这种情况的功能(一种输入有效状态数据的方法)。它有明确的意图,但它几乎完成了映射工作。

Answer Updated

为了回答自己,在这种情况下,最佳方法是使用工厂方法。最初我选择了 Automapper,但我发现自己更频繁地使用工厂方法。自动映射器有时很有用,但在很多情况下它还不够。


ORM 框架会为您处理这个问题。您只需告诉它重新水化一个对象,就会为您提供域类的常规实例(有时您只需将属性声明为 virtual 或 protected,例如在 NHibernate 中)。原因是因为在底层,它们通常对从基类派生的代理对象进行操作,从而允许您保持这些基类的完整性。

如果您想实现自己的持久层,那就完全是另一回事了。在不破坏对象中最初定义的范围约束的情况下从数据库重新水化对象可能涉及反射。您还必须考虑很多附带问题:如果您的对象引用了另一个对象,则必须先重新水化该对象,等等。

你可以看看那个教程:构建您自己的数据访问层 http://davybrion.com/blog/2009/08/build-your-own-data-access-layer-hydrating-entities/尽管在大多数情况下我不建议重新发明轮子。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

恢复域对象的最佳方法 的相关文章

  • 在 Ext JS 构造函数中将项目推入数组会产生多个项目

    我有一个我定义的 Ext JS 类 在这个班级的constructor 我将一个文本字段推送到我的项目数组上 然后添加到我的测试字符串中 数组和字符串在类定义中都声明为空 但是 如果您尝试创建多个类实例 您将看到项目数组在每个实例之间共享
  • Mootools 使用“extend”方法扩展“Function”类,导致 jQuery 无法使用

    Mootools 扩展了 Function 类 并在其中添加了一个名为 extend 的新方法 现在 jQuery 尝试使用 jQuery prototype extend 添加 扩展 功能 然而 由于 extend 已经是 jQuery
  • DDD:持久聚合

    让我们考虑一下典型的Order and 订单项目例子 假如说订单项目是的一部分Order聚合 只能通过订单添加 所以 要添加一个新的订单项目 to an Order 我们必须通过存储库加载整个聚合 将新项目添加到Order对象并再次保留整个
  • PHP 特性 - 定义通用常量

    定义可由命名空间内的多个类使用的常量的最佳方法是什么 我试图避免过多的继承 因此扩展基类不是理想的解决方案 并且我正在努力寻找使用特征的良好解决方案 这在 PHP 5 4 中是否可行 或者应该采取不同的方法 我有以下情况 trait Bas
  • 我可以在 Laravel 5.2 中创建一个继承自 User 的新类吗?

    我对 Laravel 还很陌生 使用的是迄今为止的最新版本 5 2 因此我遇到了以下困境 我知道 Laravel 附带了一个User开箱即用的类 但我想开发一个系统 在其中我可以有另外两种类型的用户 称为Researcher and Adm
  • 两个对象相互依赖。那不好吗?

    当我为我的项目构建自己的系统时 我学到了很多关于设计模式的知识 我想问你一个我找不到答案的设计问题 目前我正在使用套接字构建一个带有多个客户端的小型聊天服务器 现在我有三门课 人级其中包含昵称 年龄和房间对象等信息 房间级它保存诸如房间名称
  • 定时任务应该放在哪一层?

    我正在尝试使用分层架构来实现 DDD 应用程序 我有 基础设施层 实现应用程序的技术特定部分的层 领域层 包含领域模型的层 应用层 包含与领域模型交互的干扰的层 接口层 从外部接收事件的层 经典的 3 层 基础设施 架构非常清晰 但我的应用
  • 类是否应该有静态和非静态成员

    我试图找出一个类何时适合同时具有静态和非静态函数 又名 obj new ClassA obj gt doOOPStuff something ClassA doStaticStuff Note This example is done in
  • 什么是抽象类? [复制]

    这个问题在这里已经有答案了 当我了解抽象类时 我说 WT H 问题 创建一个无法实例化的类有什么意义呢 为什么有人想要这样的课程 什么情况下需要抽象类 如果你明白我的意思 最常见的是用作基类或接口 某些语言有单独的interface构建 有
  • Delphi:写入后代类中私有祖先的字段

    我需要修复第三方组件 该组件的类具有私有变量 该变量由其后代主动使用 TThirdPartyComponentBase class private FSomeVar Integer public end TThirdPartyCompone
  • Javascript:我应该隐藏我的实现吗?

    作为一名 C 程序员 我有一个习惯 将可以而且应该私有的东西设为私有 当 JS 类型向我公开其所有私有部分时 我总是有一种奇怪的感觉 而且这种感觉并没有被 唤起 假设我有一个类型draw方法 内部调用drawBackground and d
  • R 中使用 `UseMethod()` 与 `inherits()` 来确定对象的类

    如果我需要根据 R 对象的类以不同的方式处理它们 我可以使用if and else在单个函数内 foo lt function x if inherits x list Foo the list else if inherits x num
  • 在下面的模型中,地址不应该是值对象吗?

    From 值对象如何存储在数据库中 https stackoverflow com questions 679005 how are value objects stored in the database 假设公司和个人都有相同的邮件地址
  • 使用 NSError 检查错误的正确结构

    我正在编写各种例程 并尽力保持其整洁和重构 我正在创建的方法开始看起来与此代码类似 IBAction buttonPress id sender Create Document Shopping List with this documen
  • 什么是对象序列化和反序列化?

    什么是对象序列化 and 反序列化 序列化与读取对象的属性 然后用它们填充 DataRow 的列 最后将 DataRow 保存在数据库中等普通技术有什么区别 序列化通常是指创建可用于存储 可能在文件中 通过网络传输或仅用于进程之间传输的数据
  • 如何决定使用 IS A 还是 HAS A Relation

    public class B public String getMe return Some 假设我有一个上面的类 我们应该通过哪些参数来决定使用什么 是否是一个或有一个关系 HAS A public class A public stat
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • 在方法内部执行方法

    我目前正在 FreeCodeCamp 中进行 JavaScript 练习 我的代码应该使用的测试用例之一是函数调用 如下所示 addTogether 2 3 这是我得到的基本功能 function addTogether return 当我
  • 是否可以在不改变作为框架一部分的 DDD 模型的情况下使用 NHibernate

    我挖掘了很多关于DDD方法 无处不在的语言 聚合 存储库等 我认为 与我读到的很多内容相反 实体应该有行为而不是不可知论 我看到的所有例子都倾向于呈现实体虚拟自动属性 and an 空构造函数 受保护或最糟糕的是公开 就是这样 我认为这种对
  • 克隆和引用传递问题

    所以在过去的几天里 我一直在绞尽脑汁地试图让一个类能够正确克隆 问题是克隆不会删除 重做任何引用传递 结果是 主数据对象仍然作为引用传递 从而完全抵消了克隆的效果 这是问题的简化版本 class my class private data

随机推荐

  • 左调整 (hjust = 0) 带有自由刻度的面上的垂直 x 轴标签

    我决定重新表述这个问题 https stackoverflow com questions 60677990 ggplot facet grid x axis stepped 编辑会花费更多时间 而且在我看来也不会对OP有帮助 如何向左调整
  • (jQuery) 将 div 样式“display:none”切换为“display:inline”

    我有 2 个 div 我希望能够在单击按钮时在它们之间切换 当前使用 toggle 页面上显示的div是div1 该 div 的样式为 display inline 我的另一个 div div2 以样式 display none 开头 当d
  • 从 FFI 返回的切片创建 OsStr(ing) 的正确方法是什么?

    我有一个函数接受带参数的回调data const u8 length usize 代表一些路径 由此创建 OsStr ing 的正确方法是什么 There s from byte slice in OsStrExt 但似乎它没有检查数据是否
  • CasperJS click() 不加载新的 html

    我正在尝试使用 CasperJS click 点击在当前屏幕上生成模式的链接 当我查询正确的选择器并使用浏览器控制台中单击它时document querySelector click 它有效 但即使当我casper evaluate 这不起
  • Internet Explorer 10 和 11 中的边框半径显示问题[重复]

    这个问题在这里已经有答案了 我有一个带有边框半径的 div 它在 IE 10 和 IE11 中显示为某种片段 原因是什么 我们该如何解决这个问题 使用IE10或IE11访问本站查看效果 http css3pie com demos bord
  • 从主 Web 应用程序自动登录到另一个 ASP.NET 应用程序

    我正在主 Web 应用程序下的文件夹中运行 YetAnotherForum 的最新版本 该子文件夹在 IIS 中配置为应用程序 导航到该文件夹 并登录效果非常好 YAF 通过会员提供商进行设置并使用表单身份验证 我现在想做的是从主网站自动将
  • 布尔值是否有现有的 I18N 翻译?

    我需要根据表达式是真还是假以各种语言显示 是 或 否 目前我正在这样做 fr yml fr yes Oui no Non 一个辅助方法 def t boolean expression expression t yes t no end e
  • 多个项目共享一个 jenkinsfile

    我有多个具有类似构建步骤的项目 并且我正在考虑在这些项目中重用 Jenkinsfile 管道 我很难找到有关如何实现此类标准 据我看来 设置的文档 这是我的要求 1 Jenkinsfile存储在repo中 在多个项目之间共享 2 每个项目都
  • Spring Security 令牌身份验证 - RESTful JSON 服务

    我希望将 Spring Security 用于 Spring MVC 应用程序 该应用程序严格来说是一个 JSON Web 服务 我做了一些研究并阅读了一些文章 但还没有真正找到完整的内容 我希望应用程序完全无状态并使用基于令牌的身份验证
  • Azure 持久编排功能触发两次

    我正在尝试实现 Azure Durable Function 工作流程 每隔 6 分钟 我就会有一个 Azure TimerTrigger 函数调用一个 Azure Orchestration Function OrchestrationT
  • 在 CodeIgniter 中发送数据和重定向

    我有一个简单的 C CRUD 函数 我想发送一条消息 错误或成功 以及来自我编写的 插入 函数的重定向 有没有办法通过重定向来附加 POST 字段 在伪代码中我有 function view all set up some initial
  • python读取大型二进制文件最有效的方法是什么

    我有一个大 21 GB 文件 我想将其读入内存 然后传递给一个子例程 该子例程对我透明地处理数据 我在 Centos 6 5 上使用 python 2 6 6 因此无法升级操作系统或 python 目前 我正在使用 f open image
  • Git 克隆中的 Ansible 和 Git 权限被拒绝(公钥)

    我有一本剧本 我试图从私人存储库 GIT 克隆到服务器 我已经设置了 ssh 转发 当我 ssh 进入服务器并尝试从同一存储库手动克隆时 它成功工作 但是 当我使用 ansible 将存储库克隆到服务器时 它失败并显示 权限被拒绝公钥 这是
  • Threejs 变换矩阵排序

    我想知道 Threejs 如何对多个矩阵进行排序 例如 var mesh new THREE Mesh geometry material mesh position set 0 20 0 T transform matrix mesh r
  • XML 模式 xs:alternative 在 JSON 模式中是否可用?

    是否可以在 JSON Schema 中使用替代方案 在 XSD 中 这可以使用xs alternative元素 例如参见 如何在 XML Schema 1 1 中使用替代方案 https stackoverflow com question
  • 交叉编译器默认包含路径设置

    首先 一些背景知识 我正在尝试在 Beagleboard xM 上编写 Android 驱动程序和应用程序 我已经下载了他们的 Android 开发套件 安装了它 并且可以使用以下指示成功构建其中的所有内容http processors w
  • 纱线全局命令在 Mac 上失败

    我正在尝试使用纱线添加 vtex 但出现以下错误 Usage Error The yarn global commands have been removed in 2 x consider using yarn dlx or a thir
  • 带有 Vue 项目路由的 Azure 静态 Web 应用程序无法正常工作

    我有一个使用 Azure Static Web App 部署的 vue 项目 项目包含路由器 历史模式 功能 它在本地运行完美 但部署到 Azure 路径链接后无法正常工作 例如 当我尝试从浏览器导航访问 mysite com about
  • 我可以在 C 或 C++ 中使用二进制文字吗?

    我需要使用二进制数 我尝试写 const char x 00010000 但这没有用 我知道我可以使用与以下值相同的十六进制数00010000 但我想知道 C 中是否有二进制数的类型 如果没有 是否有其他解决方案可以解决我的问题 如果您使用
  • 恢复域对象的最佳方法

    这是一个如此简单而常见的场景 我想知道到目前为止我是如何做到的以及为什么现在遇到问题 我有这个对象 基础设施程序集的一部分 public class Queue public class QueueItem public QueueItem