Comments (6)
I think another reason for moving those methods is Unit Testing. As the Version gets only incremented in Aggregate.Fold()
on loading an aggregate from the store an error is thrown when using any method that needs an existing Aggregate
. Consider this unit test:
[Fact]
public void Full_Payment_should_leed_to_FullyPaid() {
IntegrationFixture Fixture = new();
Booking booking = new();
decimal amount = 50;
booking.BookRoom(
new BookingId(Fixture.Auto.Create<string>()),
Fixture.Auto.Create<string>(),
new StayPeriod(
LocalDate.FromDateTime(DateTime.Today),
LocalDate.FromDateTime(DateTime.Today.AddDays(2))
),
amount
);
booking.RecordPayment( // Will fail here as EnsureExists() in RecordPayment() will throw
Fixture.Auto.Create<string>(),
amount
);
Assert.True(booking.State.IsFullyPaid());
}
The only drawback I can see is that EnsureDoesntExist()
and EnsureExists()
have to changed from protected
to public
If you wan't me to create a pull request, I can do so. Or you find reasons why this approach shouldn't be done ;)
from eventuous.
OnExisting
will throw if the aggregate is not found, that's the reason for it to exist.
OnNew
will throw when it tries to store, as it expects the stream not to exist.
So, basically, calling EnsureExists
and EnsureDoesntExist
is not necessary in these cases.
The meaning for those two methods is to enforce those rules inside the model. For example, a certain operation must only instantiate the aggregate, and it cannot be performed on something that already exists. We don't need to even try loading anything from the store, as we expect to have nothing there. We use the expected version, which gets converted to stream state NoStream
and it fails on save. It happens in the app service.
However, how would you prevent this operation to be called from the app service using OnExisting
? Also, what happens if the aggregate call is made not from an app service?
from eventuous.
I will add your test. It should not throw as the booking state version should increase after BookRoom
is called and RecordPayment
should not throw.
from eventuous.
I see. I forgot about this obvious thing. There should be two versions. The original version is what we expect to have in the store, to be used for optimistic concurrency. The other version is the current state version, which should increase when state transitions happen. Ensure
methods should check the second one.
from eventuous.
Fixed in 78473bc
from eventuous.
@iappwebdev you can check the tests, I added the scenario there and tested all the outcomes, it looks good now.
from eventuous.
Related Issues (20)
- Avoid unnecessary copy of Payload and Metadata in EsdbEventStore
- Most of the AspNetCore extensions should likely be changed/moved to something more generic HOT 1
- Multitenant implementation HOT 20
- Custom queue name in RMQ gateway subscription
- Crypto Shredding Serialization/Deserialization Support
- Subscriptions sometimes skips events HOT 24
- Postgres subscription is flooding database server with polling queries HOT 3
- Postgres subscription does not automatically reconnect after database server restart HOT 1
- Promote InMemoryEventStore to the main Eventuous library
- Wrong event stream name in EventStoreDB persistent subscription events
- MongoProjector ignores exceptions returning EventHandlingStatus.Success with no logs HOT 1
- Npgsql.PostgresException: 23505: duplicate key value violates unique constraint "pk_checkpoints" HOT 1
- Postgres Store and Sample Booking Application
- Follow RFC 7807: Problem Details for HTTP APIs HOT 4
- Cannot use more than one gateway transformation HOT 1
- [Aggregate Store] Non-intrusive aggregate caching HOT 2
- MapEventuousSpyglass interferes with UseAuthentication and UseAuthorization HOT 1
- Using MapDiscoveredCommands with multiple aggregates results in error 'No handler found for command Object ' HOT 16
- Ability to return a custom return type for a command API reponse HOT 5
- SQL Server __schema__.Streams.StreamName is too big to be indexed
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from eventuous.