Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for non-Guid Identity #28

Closed
petersondrew opened this issue Jun 6, 2017 · 4 comments
Closed

Support for non-Guid Identity #28

petersondrew opened this issue Jun 6, 2017 · 4 comments

Comments

@petersondrew
Copy link
Contributor

petersondrew commented Jun 6, 2017

Continuing my saga of implementing EventStore as an IEventStore implementation, I've found that limiting identity to Guid limits the flexibility in how we store and categorize our aggregates/events, with categorization being the primary driver personally.

I envision being able to use strings, such as Order-<someGuid>, or Order-1, which is especially important for event stores that use an identity prefix to categorize events and aggregates (such as EventStore).

Any thoughts or opinions on implementing something like this? It could be as simple as replacing Guid with string, or introducing some sort of IIdentity to use. I'd be more than happy to submit a PR for this change, but wanted to know what your thoughts were.

@gautema
Copy link
Owner

gautema commented Jun 10, 2017 via email

@petersondrew
Copy link
Contributor Author

I just finally got around to finishing up a proof-of-concept implementing an IIdentity. I included an out-of-the-box GuidIdentity implementation. Those of us who need something more advanced can easily do so.

@andymacdonaldac
Copy link

We faced a similar issue, internally we name our streams typename-aggregateid so for an Availability aggregate the stream would be named something like availability-d0057d1d-b431-42f3-b8ff-bc536a9ea286.

The first thing we did was to add an ITypedEventStore interface which replicated the IEventStore interface but adds an aggregateTypeName parameter to the start of the Get and Save methods:

public interface ITypedEventStore
{
    Task<IEnumerable<IEvent>> Get(string aggretateTypeName, Guid aggregateId, int fromVersion, CancellationToken cancellationToken = default(CancellationToken));
    Task Save(string aggretateTypeName, IEnumerable<IEvent> events, CancellationToken cancellationToken = default(CancellationToken));
}

We created a new TypedRepository which implements IRepository and takes an ITypedEventStore in it's constructor.

private readonly ITypedEventStore _eventStore;

public TypedRepository(ITypedEventStore eventStore)
{
    _eventStore = eventStore ?? throw new ArgumentNullException(nameof(eventStore));
}

Then using reflection we pulled out the type name of the aggregate inside the Save and LoadAggregate methods e.g.

public async Task Save<T>(T aggregate, int? expectedVersion = null, CancellationToken cancellationToken = default(CancellationToken)) where T : AggregateRoot
{
 string typeName = aggregate.GetType().Name.ToLower();
}

and

private async Task<T> LoadAggregate<T>(Guid id, CancellationToken cancellationToken = default(CancellationToken)) where T : AggregateRoot
{
string typeName = typeof(T).Name.ToLower();
}

That type name ultimately gets passed to the ITypedEventStore implementation which is this case pushes to GetEventStore.

It's still very much a work in progress and some of the type names can probably be changed to something better but it works for us at the moment. I've attached the files we used and if anyone think's it worthwhile I'm happy to take a fork, make the changes and open a proper PR.

Code.zip

Andy

@bdongus
Copy link

bdongus commented May 15, 2018

In the beginnig I too had problems with the id being a Guid. After some meditation I wouldn't introduce a non-Guid id.
Those ids are IMHO a dependency to some sort of storage and legacy to data driven thinking. Autogenerated integer ids. As soon as you have a distributed storage scenario you are screwed using them.
I use the autogenerated integer id as clustering index and the the Guid as unique index.
That way you prevent the disk acitivity caused by the Guid as clustering index.

@gautema gautema closed this as completed Mar 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants