使用存储库和实体框架在领域事件中实现实体持久化?
我正在深入研究领域事件,并且需要一些关于出于历史原因对实体进行持久更新的建议。我的示例涉及用户实体和登录:
public class UserService
{
private UserRepository _repository;
public UserService()
{
_repository = new UserRepository();
}
public User SignIn(string username, string password)
{
var user = _repository.FindByUsernameAndPassword(username, password);
//As long as the found object is valid and an exception has not been thrown we can raise the event.
user.LastLoginDate = DateTime.Now;
user.SignIn();
return user;
}
}
public class User
{
public User(IEntityContract entityContract)
{
if (!entityContract.IsValid)
{
throw new EntityContractException;
}
}
public Guid Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public DateTime LastLoginDate { get; set; }
public void SignIn()
{
DomainEvent.Raise(new UserSignInEvent() {User = this});
}
}
public class UserSignInEvent : IDomainEvent
{
public User User { get; set; }
}
public class UserSignInHandler : Handles<UserSignInEvent>
{
public void Handle(UserSignInEvent arguments)
{
//do the stuff
}
}
因此,在我需要做这些事情的地方,我想更新用户对象 LastLoginDate 并可能记录用户由于历史原因登录的日期和时间。 我的问题是,我是否会创建存储库和上下文的新实例来保存处理程序中的更改或将某些内容传递到事件中?这就是我现在正在努力解决的问题。
I am delving into domain events and need some advice about persisting updates to an entity for history reasons. My example deals with a User entity and Signing In:
public class UserService
{
private UserRepository _repository;
public UserService()
{
_repository = new UserRepository();
}
public User SignIn(string username, string password)
{
var user = _repository.FindByUsernameAndPassword(username, password);
//As long as the found object is valid and an exception has not been thrown we can raise the event.
user.LastLoginDate = DateTime.Now;
user.SignIn();
return user;
}
}
public class User
{
public User(IEntityContract entityContract)
{
if (!entityContract.IsValid)
{
throw new EntityContractException;
}
}
public Guid Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public DateTime LastLoginDate { get; set; }
public void SignIn()
{
DomainEvent.Raise(new UserSignInEvent() {User = this});
}
}
public class UserSignInEvent : IDomainEvent
{
public User User { get; set; }
}
public class UserSignInHandler : Handles<UserSignInEvent>
{
public void Handle(UserSignInEvent arguments)
{
//do the stuff
}
}
So where I have the do the stuff, I want to update the User object LastLoginDate and possibly log the date and time the user logged in for historical reasons.
My question is, would I create a new instance of my repository and context to save the changes in the handler or pass something into the Event? This is what I am struggling with right now.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
记住上次登录日期应该是用户自己关心的问题。
您已经有了很好的扩展点 - 用户有登录方法。
用户不应该了解有关实体框架的任何信息。
因此 - User.Events 也不应该知道任何事情。
域事件处理程序也不应该知道。
那些位于“外部”(例如应用程序层)的处理程序是允许的。
但如果有必要,他们会从其他地方而不是从用户或事件中找出实体框架上下文。
正如我所见 - 这里的事件仅对于日志记录功能是必需的。
我会写这样的东西:
这段代码的坏处是服务方法是命令和查询同时进行
(它修改状态并返回结果)。
我将通过引入 来解决这个问题UserContext 将通知用户已登录。
这将不需要返回已登录的用户,
服务当前用户的责任将转移到 UserContext。
关于存储库和更新您的用户 - 我非常确定实体框架足够智能,可以知道如何跟踪实体状态更改。至少在 NHibernate 中 - 我唯一要做的就是在 httprequest 完成时刷新更改。
Remembering last login date should be concern of user itself.
You already have nice extension point - user has signIn method.
User shouldn't know anything about entity framework.
Therefore - User.Events shouldn't know anything either.
Domain event handlers shouldn't know too.
Those handlers that live "outside" (e.g. in application layer) are allowed to.
But they would figure out entity framework context from elsewhere and not from user or events if necessary.
As I see it - events here are necessary for logging functionality only.
I would write something like this:
Bad thing about this code is that service method is command and query simultaneously
(it modifies state and returns result).
I would resolve that with introducing UserContext which would be notified that user has signed in.
That would make need for returning signed in user unnecessary,
responsibility of serving current user would be shifted to UserContext.
About repository and updating Your user - I'm pretty sure entity framework is smart enough to know how to track entity state changes. At least in NHibernate - only thing I'm doing is flushing changes when httprequest finishes.