Сохранение сущностей внутри Domain Events с использованием репозитория и Entity Framework? - PullRequest
2 голосов
/ 12 мая 2011

Я углубляюсь в события в домене и нуждаюсь в совете по поводу постоянных обновлений сущности по историческим причинам.Мой пример имеет дело с сущностью пользователя и входом в систему:

    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
        }
    }

Так что, где у меня есть работа, я хочу обновить объект User LastLoginDate и, возможно, зарегистрировать дату и время, когда пользователь вошел в систему для истории.причины.У меня вопрос: могу ли я создать новый экземпляр своего хранилища и контекст, чтобы сохранить изменения в обработчике или передать что-то в событие?Вот с чем я сейчас борюсь.

1 Ответ

2 голосов
/ 12 мая 2011

Поэтому, когда у меня есть все, я хочу обновить объект User LastLoginDate и, возможно, зарегистрировать дату и время, когда пользователь вошел в систему по историческим причинам.

Запоминание даты последнего входа в систему должно заботить самого пользователя.
У вас уже есть хорошая точка расширения - у пользователя есть метод входа.

У меня вопрос: могу ли я создать новый экземпляр своего репозитория и контекст для сохранения изменений в обработчике или передать что-то в событие?

Пользователь не должен ничего знать о платформе сущностей.
Поэтому - User.Events тоже ничего не должен знать.
Домен обработчики событий тоже не должны знать.

Те обработчики, которые живут "снаружи" (например, на уровне приложения), могут.
Но они будут выяснять контекст структуры сущности из другого места, а не из пользователя или событий, если это необходимо.


На мой взгляд, события здесь необходимы только для функциональности регистрации.

Я бы написал что-то вроде этого:

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);
  }
}

Недостаток этого кода в том, что сервисный метод - это команда и запрос одновременно
(он изменяет состояние и возвращает результат).

Я бы разрешил это, введя UserContext , который будет уведомлен о том, что пользователь выполнил вход.

Это сделает ненужным возвращение зарегистрированного пользователя,
ответственность за обслуживание текущего пользователя будет перенесена на UserContext.

О хранилище и обновлении вашего пользователя. Я вполне уверен, что структура сущностей достаточно умна, чтобы знать, как отслеживать изменения состояния сущностей. По крайней мере, в NHibernate - единственное, что я делаю, это сбрасываю изменения после завершения httprequest.

...