What I learned from 3 years of CQRS and FP
I am currently setting up part of a BC for a customer, and it took me some refactoring after having not done any serious .Net for a few years, but I got there in the end; here is how I structured my current software project in .Net.
Upcoming blog post: "What I learned from 3 years of CQRS and FP" pic.twitter.com/MsfoInALtM
— Tom Janssens (@ToJans) 10 maart 2014
I think it is a reasonable base, easy to extend; some remarks:
- I use test-after, having readable scenarios that run directly on controllers, using the fake infrastructure; I verify both models, view names and redirects.
IOther*
-interfaces implement services, but are expressed in the ubiquitous language, so f.e.:- Wrong:
EmailService.SendEmail
- Right:
Notifier.SendInvitation
(you don’t wan’t things like mail composition in your domain code).
- Wrong:
IInfo
-interface implements events and domain queries, f.e.:- Wrong:
UpdateAuthenticationId
orGetItemLine(id).code
- Correct:
UserAuthenticationSucceeded
ofGetItemCode(id)
- Wrong:
- I don’t expose messages to the domain model. After all, messages are an implementation detail part of the transport layer. I learned this from
Erlang
where messages are first class members, but people still wrap the sending in a public interface. - For now infrastructure tests are manually ( a staging environment needs to be provisioned later on; the change is low in these).
- The only thing I query from the domain model in the controllers is decision state (i.e. should it proceed with the registration or not, typically using enums).
- My
IInfo
events and queries used by the domain model modify the SQL server data directly. - My
IViews
are only used to populate controller views. - If I want to debug/run locally, I can replace all the non-relevant
Infrastructure
components with theirInfrastructure.Fakes
counter-parts in the container configuration. - My
Infrastructure.Fakes
contain extra methods to verify f.e. whether an invocation has happened, and I use a distinct naming convention to make this obvious, f.e.was_invitation_sent
.
Conclusion
So, that’s it: the way I currently implemented several .Net sites for a bounded context. Tomorrow I am having a review with one of my peers, so I’m expecting it to be an interesting discussion - looking forward to it - !
I hope this makes any sense at all, and if you have further questions: shoot!
Cheers,
T.