How to get collection of aggregates of certain type from event-store builded in Marten?

433 Views Asked by At

I am new to event-sourcing and i am trying to implement an event-store as a write model in my short application. I have a user aggregate with the following code:

public sealed class User : AggregateRoot
{
    internal User(Guid id,
        string login,
        byte[] password,
        string firstName,
        string lastName,
        string mailAddress)
        : base(id)
    {
        Login = login;
        Password = password;
        FirstName = firstName;
        LastName = lastName;
        MailAddress = mailAddress;
        Enqueue(new UserCreatedDomainEvent(id,
            Login,
            Password,
            FirstName,
            LastName,
            MailAddress));
    }

    private User()
        : base(Guid.Empty)
    {
    }

    public string Login { get; private set; }
    public byte[] Password { get; private set; }
    public string FirstName { get; private set; }
    public string LastName { get; private set; }
    public string MailAddress { get; private set; }

    public void ChangePassword(byte[] password)
    {
        var areTheSame = Password == password;
    
        if (areTheSame)
        {
            return;
        }

        Password = password;
        Enqueue(new PasswordChangedDomainEvent(Id, Password));
    }

    private void Apply(UserCreatedDomainEvent @event)
    {
        Id = @event.EntityId;
        Login = @event.Login;
        Password = @event.Password;
        FirstName = @event.FirstName;
        LastName = @event.LastName;
        MailAddress = @event.MailAddress;
    }

    private void Apply(PasswordChangedDomainEvent @event) =>
        Password = @event.NewPassword;
}

Before i create a new user i need to check, is given login already taken. I know how to reconstruct an aggregate having a certain id (i use AggregateStreamAsync method for such a case), but this time i need to check the login of all aggregates before signing up the new user. How to implement such a logic? Thanks for any answer.

2

There are 2 best solutions below

0
Tore Nestenius On

You first do a query against your read side to check if a user or email already exists. You don't query the event -store directly for this kind of information.

0
Pouya Moradian On

As it is described here, you can use inline projection:

var store = DocumentStore.For(_ =>
{
    // This is all you need to create the User projected view
     _.Events.InlineProjections.AggregateStreamsWith<User>();
});

At this point, you would be able to query against User as just another document type.