首页 文章

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

提问于
浏览
5

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

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

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

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

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

  • 因为他们没有创建和设置字段值 .

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

任何帮助将不胜感激...

3 回答

  • 4

    你有选择:

    1. ORMs can work with private fields.

    据我所知,ORM(例如Entity FrameworkNHibernate)可以通过非公共设置者设置属性 .

    有一个例子可以证明它适用于实体框架 - Entity Framework, Private Constructors and Private Setters .

    如果您使用NHibernate,您的setter应该是 public/protected virtual / protected internal virtualprivate 可以使用后备字段 . 您可以在Property Access strategies in NHibernate SO问题中找到更多信息 .

    2. Reflection can be used.

    它还可用于访问私有字段/属性 . It is possible to set private property via reflection .

    3. It is not a bad practice to have public constructor to construct your entity.

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

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

    Edit:

    4. Automapper can be used.

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

    [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; }
    }
    
  • 1

    它's not true you can' t创建域对象,ORM没有公共setter . 如果您正在使用Entity Framework,它肯定可以在模型第一种方法中映射私有属性,您只需要在代码优先方法中使用public getters . 我不知道其他ORM-s怎么样 .

  • 0

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

    • XYZDomain(将知道XYZRepository并调用此接口的相应方法)

    • XYZRepository(包含接口IXYZService接口)

    • XYZSQLRepository(XYZRepository接口的实际实现) .

    现在,您可以选择使用依赖注入将XYZSQLRepository注入XYZDomain的位置 .

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

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

相关问题