POCO,行为和持久性无知

cho*_*obo 5 c# persistence domain-driven-design poco

从我所读到的POCO类应该是持久性无知,不应该包含对存储库的引用.

Q1.鉴于上述情况,我将如何填充QuestionBlocks集合?我已经读过,POCO应该包含行为,所以你不要以贫血模型结束,所以我有点困惑,因为如果没有持久性,应该如何做到这一点.如果是这样的话,你会在POCO中放入什么样的行为?

例如:

 public class Survey
    {
        public int SurveyId { get; set; }
        public string Title { get; set; }
        public int BrandId { get; set; }
        public DateTime Created { get; set; }
        public List<SurveyQuestionBlock> QuestionBlocks { get; set; }

        [ResultColumn]
        public string Name { get; set; }


        /// <summary>
        /// Constructor
        /// </summary>
        public Survey()
        {
            Created = DateTime.Now;
            QuestionBlocks = new List<SurveyQuestionBlock>();
        }
    }
Run Code Online (Sandbox Code Playgroud)

Rad*_*ler 8

我会附加另一个视图:POCO声明不依赖于任何框架的对象.对于POCO来说,POJO的wiki定义对我来说更有意义:

为了解释POJO的维基定义,我们可以说POCO对象可能不会被强制:

I.扩展预定类:

public class MyClass : AnyFramework.ObjectBase {...
Run Code Online (Sandbox Code Playgroud)

II.实现预先指定的接口

public class MyClass : AnyFramework.IHaveDependency {...
Run Code Online (Sandbox Code Playgroud)

III.包含预先指定的属性

[AnyFramework.KeyAttribute]
public class MyClass  {...
Run Code Online (Sandbox Code Playgroud)

考虑到这一点(几乎任何其他东西都是允许的)意味着要关心对象状态.换句话说,如果对象将检查业务逻辑,那么它是正确的.

但是任何POCO对象都可以框架中使用.今天主要是ORM负责持久性.所有应用程序层都使用POCO对象,而数据层负责加载和持久化(CRUD).这主要通过这些POCO对象的代理来完成.

因此,POCO可以用作完整的业务对象,可以自己处理(检查集合项的正确性,属性......).这使它与DTO不同


eul*_*rfx 4

鉴于上述情况,我将如何填充 QuestionBlocks 集合?

从数据库读取时,持久性基础设施应填充 QuestionBlocks 集合 - 重构。重建不应该调用行为,它应该只在 POCO 上设置适当的字段。这是存储库的责任。存储库通常从应用程序服务引用,这为调用实体行为奠定了基础。

如果是这样的话,那么您会在 POCO 中添加什么样的行为呢?

POCO 实体中的行为应该关注对实体本身进行更改以及维护不变量 - 即确保实体的完整性。在您的示例中,POCO 上最简单的行为应该是向调查集合中添加新问题块的方法。理想情况下,您可以将调查实体上的许多属性设置为只读:

    public class Survey
    {
        public int SurveyId { get; private set; }
        public string Title { get; private set; }
        public int BrandId { get; private set; }
        public DateTime Created { get; private set; }
        public IList<SurveyQuestionBlock> QuestionBlocks { get; private set; }
        public string Name { get; private set; }

        public void AddQuestionBlock(string questionBlockInfo)
        { 
          this.QuestionBlocks.Add(new SurveyQuestionBlock(...));
        }

        public Survey()
        {
            Created = DateTime.Now;
            QuestionBlocks = new List<SurveyQuestionBlock>();
        }
    }
Run Code Online (Sandbox Code Playgroud)

持久层应该能够通过反射设置只读属性的值。您可以更进一步,仅将问题块集合公开为只读集合,以确保它只能从实体本身内部进行修改。