我在理解存储库-域对象关系时遇到了一点问题。这是我所知道的有关域设计的一些信息(它们也可能是错误的或不准确的)。考虑到这些,我找不到从存储库中获取域对象的方法。
在 DDD 中,域应该知道并只包含业务所需的内容,其他所有内容都必须从域中清除。没关系。此外,从任何业务中提取数据访问也是一种很好的做法。应用程序不需要知道我们在哪里存储数据或我们如何存储数据。我们只要求存储库给我们一个域对象,它给我们我们想要的对象,或者其他方式也有效,我们给存储库一个域对象,它把它发送到存储。
在面向对象设计中,为域对象声明公共(public) setter 也是一种非常糟糕的方法,因为我们将无法控制谁在访问什么和更改什么。因此,最好只公开对象外部所需的内容。
因此,考虑到这些,我想不出一种方法来实现我的存储库。我可以在我的代码中使用任何 ORM 或纯 sql 并检索数据。
但是我不能从持久对象创建领域对象;
- 由于他们没有公共(public) setter ,我无法创建和设置字段值。
- 声明包含所有字段的公共(public)构造函数似乎不正确。我可能需要填写多个模型,这意味着我必须定义多个具有不同参数集的构造函数。
任何帮助将不胜感激...
最佳答案
您有以下选择:
<强>1。 ORM 可以使用私有(private)字段。
据我所知,ORM(例如 Entity Framework 、 NHibernate )可以通过非公共(public) setter 设置属性。
有一个例子可以证明它适用于 Entity Framework - Entity Framework, Private Constructors and Private Setters .
如果你使用 NHibernate,你的 setter 应该是 public/protected virtual
/protected internal virtual
或 private
可以使用支持字段。您可以在 Property Access strategies in NHibernate 中找到更多信息。所以问题。
<强>2。 Reflection可以使用。
它也可用于访问私有(private)字段/属性。 It is possible to set private property via reflection .
<强>3。使用公共(public)构造函数来构造您的实体并不是一个坏习惯。
Declaring public constructors containing all of the fields doesn't seems right. I might have several models to fill in, this means I have to define several constructors with different sets of parameters.
您的域实体只需要一个具有完整属性列表的公共(public)构造函数。尽管有多个模型要填写,但只有一个构造函数就足够了。存储库有责任正确调用构造函数并将模型映射到其参数中。
编辑:
<强>4。 Automapper可以使用。
下面的测试表明 AutoMapper可以通过私有(private) setter 映射属性。
[TestClass]
public class AutomapperTest
{
[TestMethod]
public void Test()
{
// arrange
Mapper.CreateMap<AModel, A>();
var model = new AModel { Value = 100 };
//act
var entity = Mapper.Map<A>(model);
// assert
entity.Value.Should().Be(100);
entity.Value.Should().Be(model.Value);
}
}
public class AModel
{
public int Value { get; set; }
}
public class A
{
public int Value { get; private set; }
}
关于c# - 如何从存储库中检索域对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21224265/