如何从存储库中检索域对象

我对存储库域对象关系有一点了解。 以下是我对域名设计所了解的一些信息(它们可能也是错误的或不准确的)。 考虑到这些,我找不到从存储库中获取域对象的方法。

在DDD中,域名应该只知道并包含业务所需的内容,其他所有内容都必须从域中清除。 没关系。 而且,从任何企业抽象数据访问也是一种很好的做法。 应用程序不需要知道我们存储数据的位置或存储数据的方式。 我们只要求存储库给我们一个域对象,它为我们提供了我们想要的对象,或者另一种方式也是有效的,我们给存储库一个域对象并将其发送到存储。

在面向对象设计中声明域对象的公共setter也是一种非常糟糕的方法,因为我们无法控制谁访问了什么并改变了什么。 因此,仅展示对象外部所需的内容是一种很好的做法。

因此,在我的脑海中,我无法找到实现我的存储库的方法。 我可以在我的代码中使用任何ORM或纯sql并检索数据。

但我无法从持久性对象创建域对象;

  1. 由于他们没有公共设置器,我无​​法创建和设置字段值。
  2. 声明包含所有字段的公共构造函数似乎不正确。 我可能有几个模型要填写,这意味着我必须定义几个具有不同参数集的构造函数。

任何帮助将不胜感激…

你有选择:

1. ORM可以与私人领域合作。

据我所知,ORM(例如Entity Framework , NHibernate )可以通过非公共setter设置属性。

有一个例子可以certificate它适用于entity framework – entity framework,私有构造函数和私有机构 。

如果您使用NHibernate,您的setter应该是public/protected virtual / protected internal virtualprivate支持字段可以使用。 您可以在NHibernate SO问题的Property Access策略中找到更多信息。

2.可以使用reflection 。

它还可用于访问私有字段/属性。 可以通过reflection设置私有财产 。

3.使用公共构造函数构建实体并不是一种坏习惯。

声明包含所有字段的公共构造函数似乎不正确。 我可能有几个模型要填写,这意味着我必须定义几个具有不同参数集的构造函数。

您的域实体只需要一个公共构造函数,其中包含完整的属性列表。 尽管有几个模型需要填充,但只有一个构造函数就足够了。存储库负责调用构造函数并将模型映射到其参数中。

编辑:

4.可以使用自动映射器 。

以下测试显示AutoMapper可以通过私有设置器映射属性。

 [TestClass] public class AutomapperTest { [TestMethod] public void Test() { // arrange Mapper.CreateMap(); var model = new AModel { Value = 100 }; //act var entity = Mapper.Map(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; } } 

在ORM没有公共设置器的情况下,您无法创建域对象。 如果您正在使用entity framework,它肯定可以在模型第一种方法中映射私有属性,您只需要在代码优先方法中使用公共getter 。 我不知道其他ORM-s怎么样。

我想在这里了解你的查询。 关于如何进行的一些提示。 首先,域应该知道存储库合同而不是实际的存储库基础结构。 换句话说,您可以选择具有3个类库,如下所示

  1. XYZDomain(将知道XYZRepository并调用此接口的相应方法)
  2. XYZRepository(包含接口IXYZService接口)
  3. XYZSQLRepository(XYZRepository接口的实际实现)。

现在,您可以选择使用dependency injection将XYZSQLRepository注入XYZDomain的位置。

如果需要,您还可以尝试使用事件模型来注册这些存储库。

使用自定义服务定位器来获取具体对象