Oop 恢复域对象的最佳方法
这是一个如此简单和常见的场景,我想知道我是如何管理到现在,为什么我现在有问题 我有这个对象(基础结构组件的一部分) 这将在另一个程序集中创建,如下所示Oop 恢复域对象的最佳方法,oop,domain-driven-design,factory-pattern,Oop,Domain Driven Design,Factory Pattern,这是一个如此简单和常见的场景,我想知道我是如何管理到现在,为什么我现在有问题 我有这个对象(基础结构组件的一部分) 这将在另一个程序集中创建,如下所示 var qi = new QueueItem(1,"myname",typeof(MyCommand),null); 这里没有什么不寻常的。但是,此对象将被发送到存储库,并保存到存储库中。队列对象将向存储库请求项目。存储库应重新创建QueueItem对象 但是,正如您所看到的,QueueItem属性是不变的,在创建项时,AddedOn属性只应
var qi = new QueueItem(1,"myname",typeof(MyCommand),null);
这里没有什么不寻常的。但是,此对象将被发送到存储库,并保存到存储库中。队列对象将向存储库请求项目。存储库应重新创建QueueItem对象
但是,正如您所看到的,QueueItem属性是不变的,在创建项时,AddedOn属性只应设置一次。Id属性将由队列对象设置(这并不重要)
问题是我应该如何在存储库中重新创建QueueItem?我可以有另一个构造函数,它需要所有属性的每个值,但我不希望该构造函数可用于最初创建队列项的程序集。存储库是另一个程序集的一部分,因此内部无法工作
我想提供一种工厂方法
类队列项
{
/*…其余定义..*/
public static QueueItem Restore(/* list of params*/){}
}
这至少澄清了我的意图,但我不知道为什么我不喜欢这种方法。我也可以只通过队列强制创建项目,但这意味着将队列作为依赖项传递给repo,这同样不是我想要的。为此使用特定的工厂对象似乎也有点过分了
基本上,我的问题是:在存储库中重新创建对象的最佳方式是什么,而不向另一个消费者对象公开特定的创建功能
更新
需要注意的是,我所说的存储库是指模式本身作为一种抽象,而不是ORM上的包装器。它与域对象的持久化方式或位置无关。它与存储库如何重新创建有关。另一个重要的是,我的域模型与持久化模型不同trong>。我确实使用RDBMS,但我认为这只是一个实现细节,不应该有任何重要性,因为我正在寻找一种不依赖于特定存储访问的方法
虽然这是一个特定的场景,但它基本上可以应用于将由回购恢复的每个对象
更新2
好的,我不知道我怎么能忘记AutoMapper。我有一个错误的印象,它不能映射私有字段/设置器,但它可以,我认为这是最好的解决方案
事实上,我可以说最佳解决方案(IMO)的顺序如下:
回答我自己,在这种情况下,最佳的方法是使用工厂方法。最初我选择了Automapper,但我发现自己更经常使用工厂方法。Automapper有时可能有用,但在相当多的情况下它是不够的。ORM框架将为您解决这一问题。您只需告诉它重新水化o对象和域类的常规实例将提供给您(有时您只需将属性声明为虚拟或受保护,例如在NHibernate中)。原因是在后台,它们通常对派生自基类的代理对象进行操作,从而使您能够保持这些基类的完整性 但是,如果您想实现自己的持久化层,那就完全是另外一回事了。在不打破对象中最初定义的范围约束的情况下,从数据库中重新水化对象可能会涉及反射。您还必须考虑许多次要问题:如果您的对象引用了另一个对象,则必须将之前的那个水化
您可以看看该教程:尽管我不建议在大多数情况下重新发明轮子。您谈到了对象本身的工厂方法。但DDD声明实体应由工厂创建。因此,您应该拥有一个QueueItemFactory,可以创建新的QueueItems并还原现有的QueueItems 好吧,我不知道我怎么能忘记AutoMapper
我希望我能忘记AutoMapper。仅仅看到这个可怕的API就让我不寒而栗。这个问题不依赖于数据库。当我说存储库时,我的意思是它完全是一个抽象。即使使用ORM,我仍然必须将ORM实体映射到域实体。我已经用这个澄清更新了我最初的问题n我猜您“只有”有以下选项:内部关键字+[InternalsVisibleTo(YourReposAssembly)]或反射或还原()方法或子类QueueItem在YourReposAssembly中…谢谢你的建议,但我认为我找到了最好的方法。我更新了问题。在这种情况下,工厂是创建实体的好选择。但这里我想还原,这是存储库的责任。我认为工厂不应该还原实体。有几个l执行恢复的方法,目前我更喜欢实体本身的静态工厂方法。实际上,存储库将工作委托给工厂(如果要恢复对象,还需要一个实例)。如果您要执行CQR,则存储库可能会将工作委派给某个对象上重播域事件的对象。存储库只是一个集合,用于保存聚合根的列表。在您的情况下,存储库将承担多个不同的责任(即更改原因).话虽如此,大多数人已经使用NHibernate;这使得
public static QueueItem Restore(/* list of params*/){}
}