我的项目结构如下:
网站 - >服务 - >存储库 - >域对象
我使用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也不是那么好,但是这个示例显示逻辑可能比普通的默认值更复杂。
非常感谢
答案 0 :(得分:1)
假设您使用数据库存储来存储项目(而不是使用它们进行操作),我认为您可以使用单独的类来实例化对象。 (正如你所描述的某种工厂。)
例如,在我的应用程序中,我经常使用UserManager类。此类根据登录方法(电子邮件+密码,社交ID等)完成与用户创建相关的所有工作。此类也可能包含更改密码等的方法。
UPD:
我使用数据层作为知道如何从/向数据库创建/更新/读取/删除对象的东西。此外,与db一起使用的类可以使用selectByThis,selectByThat等方法。因此,除了db层之外,您永远不需要在代码中的某处编写特定于db的内容。 (我的意思是你永远不需要写像.Where(a => a.SomeProp == true),你只需要使用特殊的方法,所以如果你改变数据库,你只需要改变你的数据库层,现在整个项目。)
所以是的,当我需要一些特殊逻辑来初始化对象时,我使用单独的类。 (就像某种经理一样。)那个班做了所有的工作然后只是告诉db层:“嘿,我做了所有的工作,所以只为我保存这个对象!”
它简化了您的维护。而且,这是如何遵循单一责任的规则。一个类初始化,做一些工作,另一个类保存。