使用存储库和实体框架进行域事件中的实体维护? [英] Entity persitance inside Domain Events using a repository and Entity Framework?

查看:168
本文介绍了使用存储库和实体框架进行域事件中的实体维护?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在深入研究域事件,需要一些有关持久更新到实体的建议。我的例子涉及用户实体和登录:

  public class UserService 
{
private UserRepository _repository ;

public UserService()
{
_repository = new UserRepository();
}

public User SignIn(string username,string password)
{
var user = _repository.FindByUsernameAndPassword(username,password);
//只要找到的对象有效,并且没有抛出异常,我们可以引发事件。
user.LastLoginDate = DateTime.Now;
user.SignIn();
返回用户;
}
}

public class User
{
public User(IEntityContract entityContract)
{
if(!entityContract。 IsValid)
{
throw new EntityContractException;
}
}

public Guid Id {get;组; }
public string Username {get;组; }
public string Password {get;组; }
public DateTime LastLoginDate {get;组; }

public void SignIn()
{
DomainEvent.Raise(new UserSignInEvent(){User = this});
}
}

public class UserSignInEvent:IDomainEvent
{
public User User {get;组; }
}


public class UserSignInHandler:处理< UserSignInEvent>
{
public void Handle(UserSignInEvent arguments)
{
//做东西
}
}

所以我做了这些东西,我想更新User对象LastLoginDate,并可能记录用户登录的日期和时间是为了历史原因。
我的问题是,我会创建一个我的存储库和上下文的新实例来保存处理程序中的更改或将事情传递给事件?这是我正在努力的现在。

解决方案


所以我做的东西,我想更新User对象LastLoginDate,并且可能会记录用户历史原因登录的日期和时间。


记住上次登录日期应该是用户本身的关注。

你已经有很好的扩展点 - 用户有我的问题是,我将创建一个新的我的存储库和上下文实例来保存处理程序中的更改或传递一些事情。进入事件?


用户不应该知道实体框架的任何内容。

因此 - User.Events shouldn

事件处理程序也不应该知道。



那些处于外部的处理程序(例如在应用层)被允许。

但是,如果需要,他们将从别处找出实体框架上下文,而不是从用户或事件中获取。



< hr>

正如我所看到的 - 这里的事件对于仅记录功能是必需的。



我会写这样的东西: / p>

  public class Log inService {
private Users _users;
public LoginService(Users users){
_users = users;
}
public User SignIn(string username,string password){
var user = _users.ByUsernameAndPassword(username,password);
user.SignIn();
返回用户;
}
}

public class User {
public DateTime LastLoginDate {get;组; }
public void SignIn(){
LastLoginDate = DateTime.Now;
Raise(new SignedIn(this));
}
public class SignedIn:DomainEvent< User> {
public SignedIn(User user):base(user){}
}
}

//域外模型
public class OnUserSignedIn:IEventHandler< User.SignedIn> {
public void Handle(User.SignedIn e){
var u = e.Source;
var message =User {0} {1}登录{1}
.With(u.Name,u.LastName,u.LastLoginDate);
Console.WriteLine(message);
}
}

这个代码的坏事是,服务方法是命令并同时查询

(它修改状态并返回结果)。



我将通过引入 UserContext ,将被通知用户已登录。



这将需要返回登录用户不必要的,

服务当前用户的责任将被转移到UserContext。



关于存储库和更新您的用户 - 我很漂亮确实的实体框架足够聪明才能知道如何跟踪实体状态的变化。至少在NHibernate中 - 只有当httprequest完成时,我正在做的是刷新更改。


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.

解决方案

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.

Remembering last login date should be concern of user itself.
You already have nice extension point - user has signIn method.

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?

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:

public class LoginService{
   private Users _users;
   public LoginService(Users users){
     _users = users;
   }         
   public User SignIn(string username, string password){
     var user = _users.ByUsernameAndPassword(username, password);
     user.SignIn();
     return user;
   }
 }

public class User{
   public DateTime LastLoginDate { get; set; }      
   public void SignIn(){
     LastLoginDate = DateTime.Now;
     Raise(new SignedIn(this));
   }
   public class SignedIn:DomainEvent<User>{
     public SignedIn(User user):base(user){}
   }
}

//outside of domain model
public class OnUserSignedIn:IEventHandler<User.SignedIn>{
  public void Handle(User.SignedIn e){
    var u=e.Source;
    var message="User {0} {1} logged in on {1}"
      .With(u.Name,u.LastName,u.LastLoginDate);
    Console.WriteLine(message);
  }
}

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.

这篇关于使用存储库和实体框架进行域事件中的实体维护?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆