gpt4 book ai didi

oop - 恢复域对象的最佳方式

转载 作者:行者123 更新时间:2023-12-04 23:52:00 25 4
gpt4 key购买 nike

这是一个如此简单和常见的场景,我想知道我是如何管理到现在的以及为什么我现在遇到问题。

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

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 属性将由 Queue 对象设置(这并不重要)。

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

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

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

这至少清除了意图,但我不知道为什么我不喜欢这种方法。我也可以强制仅由 Queue 创建项目,但这意味着将 Queue 作为依赖项传递给 repo,这又不是我想要的。为此拥有一个特定的工厂对象,似乎也太过分了。

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

更新

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

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

更新2

好吧,我不知道我怎么会忘记 AutoMapper。我的错误印象是它不能映射私有(private)字段/setter,但它可以,我认为这是最好的解决方案。

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

  1. 如果可用,直接反序列化。
  2. 自动 map 。
  3. 域对象本身的工厂方法。

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

回答 已更新

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

最佳答案

ORM 框架会为您解决这个问题。你只需要告诉它重新水化一个对象,域类的一个常规实例就会被提供给你(有时你只需要将属性声明为虚拟的或 protected ,例如在 NHibernate 中)。原因是因为在幕后,它们通常对从您的基类派生的代理对象进行操作,从而使您可以保持这些基类的完整性。

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

你可以看看那个教程:Build Your Own dataAccess Layer尽管在大多数情况下我不建议重新发明轮子。

关于oop - 恢复域对象的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10040950/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com