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

时间:2015-03-30 21:16:01

标签: c# asp.net-mvc-5 entity-framework-6 repository-pattern poco

我的项目结构如下:

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

我使用Entity Framework 6和Autofac。

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

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

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也不是那么好,但是这个示例显示逻辑可能比普通的默认值更复杂。

非常感谢

1 个答案:

答案 0 :(得分:1)

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

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

UPD:

我使用数据层作为知道如何从/向数据库创建/更新/读取/删除对象的东西。此外,与db一起使用的类可以使用selectByThis,selectByThat等方法。因此,除了db层之外,您永远不需要在代码中的某处编写特定于db的内容。 (我的意思是你永远不需要写像.Where(a => a.SomeProp == true),你只需要使用特殊的方法,所以如果你改变数据库,你只需要改变你的数据库层,现在整个项目。)

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

它简化了您的维护。而且,这是如何遵循单一责任的规则。一个类初始化,做一些工作,另一个类保存。