在存储库模式中,如何集成域对象工厂

In a repository pattern, how can I integrate domain object factories

我有一个结构如下的项目:

网站 --> 服务 --> 存储库 --> 域对象

我使用 Entity Framework 6 和 Autofac。

有人告诉我应该从我的域对象中删除所有构造逻辑,以便它们尽可能保持 POCO。问题是,我有一些属性应该在创建新对象时初始化,例如 CreationDate 和 UserIdCreatedBy

例如,如果我有一个 Client 对象,我将在 Client class 构造函数中使用以下逻辑:

public class Client
{
    public Client()
    {
        this.CreationDate = DateTime.UtcNow;
        if (Thread.CurrentPrincipal is CustomPrincipal
            && ((CustomPrincipal)Thread.CurrentPrincipal).CustomIdentity != null
            && ((CustomPrincipal)Thread.CurrentPrincipal).CustomIdentity.User != null)
        {
            this.UserIdCreatedBy = ((CustomPrincipal)Thread.CurrentPrincipal).CustomIdentity.User.UserId;
        }
    }

    ... Properties and such
}

所以现在,我想将此构造函数逻辑从域对象中取出到该对象的工厂中。我怎样才能优雅地做到这一点,以便 Entity Framework 在我调用 MyContext.Clients.Create() 时使用它?这可能吗?我知道调用 Thread 的 CurrentPrincipal 也不是那么好,但它是为了显示逻辑可能比普通默认值更复杂的示例。

非常感谢

假设您使用数据库存储来存储项目(不是为了对它们进行操作),我认为您可以使用单独的 class 来实例化对象。 (您描述的某种工厂。)

例如,在我的应用程序中,我经常使用 UserManager class。 class 根据登录方法(电子邮件+密码、社交 ID 等)完成与用户创建相关的所有工作。此外,此 class 可能包含更改密码等的方法。

更新:

我将数据层用作知道如何 create/update/read/delete 对象 from/to 数据库的东西。此外,与 db 一起使用的 class 可以具有 selectByThis、selectByThat 等方法。因此,除了 db 层之外,您永远不需要在代码中的某处编写特定于 db 的内容。 (我的意思是你永远不需要写类似 .Where(a => a.SomeProp == true 的东西),你只需要为此使用特殊的方法,所以如果你改变数据库,你只需要改变你的数据库层,现在整个项目。)

所以是的,当我需要一些特殊的逻辑来初始化对象时,我使用单独的 class。 (就像某种经理。)class 完成所有工作,然后只告诉数据库层:“嘿,我完成了所有工作,所以请为我保存这个对象!”

为您简化维护。此外,这就是如何遵循单一责任规则。一个 class 初始化,做一些工作,另一个 class 保存。