Domain queries in CQRS - domain-driven-design

We are trying out CQRS. We have a validation situation where a CustomerService (domain service) needs to know whether or not a Customer exists. Customers are unique by their email address. Our Customer repository (a generic repository) only has Get(id) and Add(customer). How should the CustomerService find out if the Customer exists?

Take a look at this blog post: Set based validation in the CQRS Architecture.
It addresses this very issue. It's a complex issue to deal with in CQRS. What Bjarte is suggesting is to query the reporting database for existing Customer e-mail addresses and issue a Compensating Command (such as CustomerEmailAddressIsNotUniqueCompensatingCommand) back to the Domain Model if an e-mail address was found. You can then fire off appropriate events, which may include an UndoCustomerCreationEvent.
Read through the comments on the above blog post for alternative ideas.
Adam D. suggests in a comment that validation is a domain concern. As a result, you can store ReservedEmailAddresses in a service that facilitates customer creation and is hydrated by events in your event store.
I'm not sure there's an easy solution to this problem that feels completely clean. Let me know what you come up with!
Good luck!

This issues does not have to be that complex:
Check your reporting store for customer uniqueness before submitting the UpdateCustomer command.
Add a constraint to your DB for uniqueness on email address. When executing the command, handle the exception and send a notification to the user using a reply channel. (hences never firing CustomerUpdated events to the reporting store.
Use the database for what it's good for and don't get hung up on ORM limitations.

This post by Udi Dahan http://www.udidahan.com/2009/12/09/clarified-cqrs/ contains the following paragraph:
"Also, we shouldn’t need to access the query store to process commands – any state that is needed should be managed by the autonomous component – that’s part of the meaning of autonomy."
I belive Udi suggested simply adding a unique constraint to the database.
But if you don't feel like doing that, based on the statement above, I would suggest just adding the "ByEmail" method to the repository and be done with it - but then again Udi would probably have a better suggestion..

Hope I am not too late...but we faced a similar situation in our project, we actually intercept the command executor and attach it with the set of rules created for that command, which in turn uses a query to fetch the data.
So in this case, We can have a class by the name, CustomerEmailMustBeUniqueRule which is fetched by the RuleEngine when the command "RegisterCustomerCommand" is about to be executed by RegisterCustomerCommandExecutor. This rule class has the responsibility to query the database to find if the email id exist and stop the execution by raising the invalid flag...

Related

Are GetById, GetByX CRUD or Business logic methods or both of them

Colleague of mine told me - we don't have a Business logic, we only have CRUD like GetById, GetBySearchTerm, GetByParentID....so I started to wondering about these words.
After reading about DDD, those methods are CRUD, they have a mechanism to fetch data (also store, update, delete...) based on some specific code (usually SQL).
If Business analyst say me: "We need to show data about specific customer".
In my opinion this IS (GetById) a Business process, GetById should be placed inside Business logic part of the application and it contacts repository to fetch a data. Repository with CRUD methods is responsible to persist data based on some criteria.
I Know this question can lead to debate to have repository with atomic methods (GetById, GetBySearchTerm, GetByParentiId...) but my question is only simple - are those methods are CRUD or Business logic methods.
The short answer is that you should not be querying your domain model for any reason other than domain operations that are part of the write / transactional side of things. This side of things is more interested in commands issued at your domain in order to do / perform operations.
Anything related to displaying data should come from as simple a query / read model as is possible.
If you find that your queries require domain interaction you probably have a scenario where you may need to tell your domain to do something and, once completed, you can request the data through the query side.
Not every application is a DDD application. Some applications are just simple CRUD
The business logic would be the part of the application where you validate inputs (like get by id and id is a number between 1 and 99999). This then is passed on to the repository for the actual query.
But if your application is really a crud application then trying to apply DDD isn't going to help you.
Those methods can't be the business methods at all. As a CQRS practitioner i would suggest you to have different models for command and query side. May be you create a different bounded context that serves the whole reading (Query) process (You can create anemic /DTOs here) and another domain model that serves pure business logic purpose.
You can take a look at my blog for command and query separation.
https://aspxsushil.wordpress.com/2015/10/18/command-and-query-object-pattern/

DDD - can a repository fetch an aggregate by something other than its identifier?

I model a User as an aggregate root and a User is composed of an Identifier value object as well as an Email value object. Both value objects can uniquely identify a User, however the email is allowed to change and the identifier cannot.
In most examples of DDD I have seen, a repository for an aggregate root only fetches by identifier. Would it be correct to add another method that fetches by email to the repository? Am I modeling this poorly?
I would say yes, it is appropriate for a repository to have methods for retrieving aggregates by something other than the identity. However, there are some subtleties to be aware of.
The reason that many repository examples only retrieve by ID is based on the observation that repositories coupled with the structure of aggregates cannot fulfill all query requirements. For instance, if you have a query which calls for some fields from an aggregate as well as some fields for a referenced aggregate and some summary data, the corresponding aggregate classes cannot be used to represent this data. Instead, a dedicated read-model is needed. Therefore, querying responsibilities are decoupled from the repository. This have several advantages (queries can be served by a dedicated de-normalized store) and it is the principal paradigm of CQRS. In this type of architecture, domain classes are only retrieved by the repository when some behavior needs to execute. All read-only use cases are served by a read-models.
The reason that I think it appropriate for a repository to have a GetByEmail method is based on YAGNI and battling complexity. You an allow your application to evolve as requirements change and grow. You don't need to jump to CQRS and separate read/write stores right away. You can start with a repository that also happens to have a query method. The only thing to keep in mind is that you should try to retrieve entities by ID when you need to invoke some behavior on those entities.
I would put this functionality into a service / business layer that is specific to your User object. Not every object is going to have an Email identifier. This seems more like business logic than the responsibility of the repository. I am sure you already know this, but here is good explanation of what I am talking about.
I would not recommend this, but you could have a specific implementation of your repository for a User that exposes a GetByEmail(string emailAddress) method, but I still like the service idea.
I agree with what eulerfx has answered:
You need to ask yourself why you need to get the AR using something
other than the ID.
I think it would be rather obvious that you do not have the ID but you do have some other unique identifier such as the e-mail address.
If you go with CQRS you need to first determine whether the data is important to the domain or only to the query store. If you require the data to be 100% consistent then it changes things slightly. You would, for instance, need 100% consistency if you are checking whether an e-mail address exists in order to satisfy the unique constraint. If the queried data is at any time stale you will probably run into problems.
Remember that a repository represents a collection of sorts. So if you do not need to actually operate on the AR (command side) but you have decided that where you are using your domain is appropriate then you could always go for a ContainsEMailAddress on the repository; else you could have a query side for your domain data store also since your domain data store (OLTP type store) is 100% consistent whereas your query store (OLAP type store) may only be eventually consistent, as is typical of CQRS with a separate query store.
In most examples of DDD I have seen, a repository for an aggregate
root only fetches by identifier.
I'd be curious to know what examples you've looked at. According to the DDD definition, a Repository is
A mechanism for encapsulating storage, retrieval, and search behavior
which emulates a collection of objects.
Search obviously includes getting a root or a collection of roots by all sorts of criteria, not only their ID's.
Repository is a perfect place for GetCustomerByEmail(), GetCustomersOver18(), GetCustomersByCountry(...) and so on.
Would it be correct to add another method that fetches by email to the repository? - I would not do that. In my opinion a repository should have only methods for getting by id, save and delete.
I'd rather ask why you don't have user id in the command handler in which you want to fetch the user and call a domain method on it. I don't know what exactly you are doing, but for the login/register scenario, I would do following. When a user logs in, he passes an email address and a password, and you do a query to authenticate the user - this would not use domain or repository (that is just for commands), but would use some query implementation which would return some UserDto which would contain user id, from this point you have the user id. Next scenario is registration. The command handler to create a new user would create a new user entity, then the user needs to log in.

When to update audit fields? DDD

I have a Meeting Object:
Meeting{id, name, time, CreatedBy, UpdatedBy}
and a
MeetingAssignee{id, MeetingID, EmployeeId, CreatedBy, UpdatedBy)
Meeting, as Aggregate root, has a method AssignEmployee.
I was about to pass in the current user to the Meeting object as I call AssignEmployee, so that it can update its audit fields accordingly.
But this doesn't seem right - is it? Obviously I can keep the audit fields public and change them later - perhaps at service level?
What is everyone's else preferred method for updating these fields?
Please note: We are not using Nhibernate, but a custom ORM which does not have anything automatic in place.
Thanks.
Auditing and logging are fun as they are usually needed everywhere in the application and they are both requirements (logging is a requirement from the OPs guys).
Without knowing much of your model, and since auditing must be a requirement, I would pass the current user to AssignEmployee and instead of having a line there that says AuditBlahBlahBlah, I would add an event (maybe MeetingUpdated or AssigneeAdded... you'll find a good name) and that event gets dispatched to the class that does the auditing. In this way the Meeting class has no clue about auditing and dispatches business events for auditing purposes (which, in my view, is very DDDish).
I wonder what other people might say (hopefully, I can learn something new!)
Consider using domain events.
Everything interesting in your domain model should raise an event shouting aloud of what just have happened. From outside, just attach log handler that dumps them in db or somewhere else.
That way - you don`t need to mess up your domain with some kind of IAuditService's.
Even better - domain model can use eventing as a way to communicate inside of itself.
To show why that`s a good idea - visualize that we are describing domain model of morning, sunrise and flowers.
Is it responsibility of sun to tell all the flowers that they should open? Not really. Sun just needs to shine brightly enough (to raise an event), light must travel down to earth (there must be some kind of infrastructure that makes eventing possible) and flowers must react themselves when receiving light (other domain models should handle events).
Another analogy - it's responsibility of driver to see what's the color of traffic lights.
You could possibly make the call to the audit service from the service layer when persisting or updating the entities, with the audit service having being injected into any services that require audit functionality, and persist the newly created entities as quickly as possible.
I see how it could be hard to work out how-and-when to audit, especially if your entities are going to exist as usable entities in the system sometime before being persisted. Even if they exist for some time before being persisted, maybe you could create in-memory audit data, containing the details of their creation and then persist that when the entities are eventually persisted. Or have the created-by, created-on, modified-by, modified-on, etc. data set as private fields in the entity and write it out to an audit log when the entity is persisted?
I'd be interested in what the trade-offs would be.
I think that the auditing properties are not a concern of your domain model. If all the use cases available in your application services layer use the domain model to make changes in the system, and the aggregate roots publish anything that has happened as Domain Events later on you can implement a handler for any event and it saves them in the audit log format you need.

CQRS Event Sourcing: Validate UserName uniqueness

Let's take a simple "Account Registration" example, here is the flow:
User visit the website
Click the "Register" button and fill out the form, click the "Save" button
MVC Controller: Validate UserName uniqueness by reading from ReadModel
RegisterCommand: Validate UserName uniqueness again (here is the question)
Of course, we can validate UserName uniqueness by reading from ReadModel in the MVC controller to improve performance and user experience. However, we still need to validate the uniqueness again in RegisterCommand, and obviously, we should NOT access ReadModel in Commands.
If we do not use Event Sourcing, we can query the domain model, so that's not a problem. But if we're using Event Sourcing, we are not able to query the domain model, so how can we validate UserName uniqueness in RegisterCommand?
Notice: User class has an Id property, and UserName is not the key property of the User class. We can only get the domain object by Id when using event sourcing.
BTW: In the requirement, if the entered UserName is already taken, the website should show the error message "Sorry, the user name XXX is not available" to the visitor. It's not acceptable to show a message, that says, "We are creating your account, please wait, we will send the registration result to you via Email later", to the visitor.
Any ideas? Many thanks!
[UPDATE]
A more complex example:
Requirement:
When placing an order, the system should check the client's ordering history, if he is a valuable client (if the client placed at least 10 orders per month in the last year, he is valuable), we make 10% off to the order.
Implementation:
We create PlaceOrderCommand, and in the command, we need to query the ordering history to see if the client is valuable. But how can we do that? We shouldn't access ReadModel in command! As Mikael said, we can use compensating commands in the account registration example, but if we also use that in this ordering example, it would be too complex, and the code might be too difficult to maintain.
If you validate the username using the read model before you send the command, we are talking about a race condition window of a couple of hundred milliseconds where a real race condition can happen, which in my system is not handled. It is just too unlikely to happen compared to the cost of dealing with it.
However, if you feel you must handle it for some reason or if you just feel you want to know how to master such a case, here is one way:
You shouldn't access the read model from the command handler nor the domain when using event sourcing. However, what you could do is to use a domain service that would listen to the UserRegistered event in which you access the read model again and check whether the username still isn't a duplicate. Of course you need to use the UserGuid here as well as your read model might have been updated with the user you just created. If there is a duplicate found, you have the chance of sending compensating commands such as changing the username and notifying the user that the username was taken.
That is one approach to the problem.
As you probably can see, it is not possible to do this in a synchronous request-response manner. To solve that, we are using SignalR to update the UI whenever there is something we want to push to the client (if they are still connected, that is). What we do is that we let the web client subscribe to events that contain information that is useful for the client to see immediately.
Update
For the more complex case:
I would say the order placement is less complex, since you can use the read model to find out if the client is valuable before you send the command. Actually, you could query that when you load the order form since you probably want to show the client that they'll get the 10% off before they place the order. Just add a discount to the PlaceOrderCommand and perhaps a reason for the discount, so that you can track why you are cutting profits.
But then again, if you really need to calculate the discount after the order was places for some reason, again use a domain service that would listen to OrderPlacedEvent and the "compensating" command in this case would probably be a DiscountOrderCommand or something. That command would affect the Order Aggregate root and the information could be propagated to your read models.
For the duplicate username case:
You could send a ChangeUsernameCommand as the compensating command from the domain service. Or even something more specific, that would describe the reason why the username changed which also could result in the creation of an event that the web client could subscribe to so that you can let the user see that the username was a duplicate.
In the domain service context I would say that you also have the possibility to use other means to notify the user, such like sending an email which could be useful since you cannot know if the user is still connected. Maybe that notification functionality could be initiated by the very same event that the web client is subscribing to.
When it comes to SignalR, I use a SignalR Hub that the users connects to when they load a certain form. I use the SignalR Group functionality which allows me to create a group which I name the value of the Guid I send in the command. This could be the userGuid in your case. Then I have Eventhandler that subscribe to events that could be useful for the client and when an event arrives I can invoke a javascript function on all clients in the SignalR Group (which in this case would be only the one client creating the duplicate username in your case). I know it sounds complex, but it really isn't. I had it all set up in an afternoon. There are great docs and examples on the SignalR Github page.
I think you are yet to have the mindset shift to eventual consistency and the nature of event sourcing. I had the same problem. Specifically I refused to accept that you should trust commands from the client that, using your example, say "Place this order with 10% discount" without the domain validating that the discount should go ahead. One thing that really hit home for me was something that Udi himself said to me (check the comments of the accepted answer).
Basically I came to realise that there is no reason not to trust the client; everything on the read side has been produced from the domain model, so there is no reason not to accept the commands. Whatever in the read side that says the customer qualifies for discount has been put there by the domain.
BTW: In the requirement, if the entered UserName is already taken, the website should show error message "Sorry, the user name XXX is not available" to the visitor. It's not acceptable to show a message, say, "We are creating your account, please wait, we will send the registration result to you via Email later", to the visitor.
If you are going to adopt event sourcing & eventual consistency, you will need to accept that sometimes it will not be possible to show error messages instantly after submitting a command. With the unique username example the chances of this happening are so slim (given that you check the read side before sending the command) its not worth worrying about too much, but a subsequent notification would need to be sent for this scenario, or perhaps ask them for a different username the next time they log on. The great thing about these scenarios is that it gets you thinking about business value & what's really important.
UPDATE : Oct 2015
Just wanted to add, that in actual fact, where public facing websites are concerned - indicating that an email is already taken is actually against security best practices. Instead, the registration should appear to have gone through successfully informing the user that a verification email has been sent, but in the case where the username exists, the email should inform them of this and prompt them to login or reset their password. Although this only works when using email addresses as the username, which I think is advisable for this reason.
There is nothing wrong with creating some immediately consistent read models (e.g. not over a distributed network) that get updated in the same transaction as the command.
Having read models be eventually consistent over a distributed network helps support scaling of the read model for heavy reading systems. But there's nothing to say you can't have a domain specific read model thats immediately consistent.
The immediately consistent read model is only ever used to check data before issuing a command, you should never use it for directly displaying read data to a user (i.e. from a GET web request or similar). Use eventually consistent, scaleable read models for that.
About uniqueness, I implemented the following:
A first command like "StartUserRegistration". UserAggregate would be created no matter if user is unique or not, but with a status of RegistrationRequested.
On "UserRegistrationStarted" an asynchronous message would be sent to a stateless service "UsernamesRegistry". would be something like "RegisterName".
Service would try to update (no queries, "tell don't ask") table which would include a unique constraint.
If successful, service would reply with another message (asynchronously), with a sort of authorization "UsernameRegistration", stating that username was successfully registered. You can include some requestId to keep track in case of concurrent competence (unlikely).
The issuer of the above message has now an authorization that the name was registered by itself so now can safely mark the UserRegistration aggregate as successful. Otherwise, mark as discarded.
Wrapping up:
This approach involves no queries.
User registration would be always created with no validation.
Process for confirmation would involve two asynchronous messages and one db insertion. The table is not part of a read model, but of a service.
Finally, one asynchronous command to confirm that User is valid.
At this point, a denormaliser could react to a UserRegistrationConfirmed event and create a read model for the user.
Like many others when implementing a event sourced based system we encountered the uniqueness problem.
At first I was a supporter of letting the client access the query side before sending a command in order to find out if a username is unique or not. But then I came to see that having a back-end that has zero validation on uniqueness is a bad idea. Why enforce anything at all when it's possible to post a command that would corrupt the system ? A back-end should validate all it's input else you're open for inconsistent data.
What we did was create an index table at the command side. For example, in the simple case of a username that needs to be unique, just create a user_name_index table containing the field(s) that need to be unique. Now the command side is able to query a username's uniqueness. After the command has been executed it's safe to store the new username in the index.
Something like that could also work for the Order discount problem.
The benefits are that your command back-end properly validates all input so no inconsistent data could be stored.
A downside might be that you need an extra query for each uniqueness constraint and you are enforcing extra complexity.
I think for such cases, we can use a mechanism like "advisory lock with expiration".
Sample execution:
Check username exists or not in eventually consistent read model
If not exists; by using a redis-couchbase like keyvalue storage or cache; try to push the username as key field with some expiration.
If successful; then raise userRegisteredEvent.
If either username exists in read model or cache storage, inform visitor that username has taken.
Even you can use an sql database; insert username as a primary key of some lock table; and then a scheduled job can handle expirations.
Have you considered using a "working" cache as sort of an RSVP? It's hard to explain because it works in a bit of a cycle, but basically, when a new username is "claimed" (that is, the command was issued to create it), you place the username in the cache with a short expiration (long enough to account for another request getting through the queue and denormalized into the read model). If it's one service instance, then in memory would probably work, otherwise centralize it with Redis or something.
Then while the next user is filling out the form (assuming there's a front end), you asynchronously check the read model for availability of the username and alert the user if it's already taken. When the command is submitted, you check the cache (not the read model) in order to validate the request before accepting the command (before returning 202); if the name is in the cache, don't accept the command, if it's not then you add it to the cache; if adding it fails (duplicate key because some other process beat you to it), then assume the name is taken -- then respond to the client appropriately. Between the two things, I don't think there'll be much opportunity for a collision.
If there's no front end, then you can skip the async look up or at least have your API provide the endpoint to look it up. You really shouldn't be allowing the client to speak directly to the command model anyway, and placing an API in front of it would allow you to have the API to act as a mediator between the command and read hosts.
It seems to me that perhaps the aggregate is wrong here.
In general terms, if you need to guarantee that value Z belonging to Y is unique within set X, then use X as the aggregate. X, after all, is where the invariant really exists (only one Z can be in X).
In other words, your invariant is that a username may only appear once within the scope of all of your application's users (or could be a different scope, such as within an Organization, etc.) If you have an aggregate "ApplicationUsers" and send the "RegisterUser" command to that, then you should be able to have what you need in order to ensure that the command is valid prior to storing the "UserRegistered" event. (And, of course, you can then use that event to create the projections you need in order to do things such as authenticate the user without having to load the entire "ApplicationUsers" aggregate.

Having trouble putting real-world logic into the DDD domain layer

Despite having studied Domain Driven Design for a long time now there are still some basics that I simply figure out.
It seems that every time I try to design a rich domain layer, I still need a lot of Domain Services or a thick Application Layer, and I end up with a bunch of near-anemic domain entities with no real logic in them, apart from "GetTotalAmount" and the like. The key issue is that entities aren't aware of external stuff, and it's bad practice to inject anything into entities.
Let me give some examples:
1. A user signs up for a service. The user is persisted in the database, a file is generated and saved (needed for the user account), and a confirmation email is sent.
The example with the confirmation email has been discussed heavily in other threads, but with no real conclusion. Some suggest putting the logic in an application service that gets an EmailService and FileService injected from the infrastructure layer. But then I would have business logic outside of the domain, right? Others suggest creating a domain service that gets the infrastructure services injected - but in that case I would need to have the interfaces of the infrastructure services inside the domain layer (IEmailService and IFileService) which doesn't look too good either (because the domain layer cannot reference the infrastructure layer). And others suggest implementing Udi Dahan's Domain Events and then having the EmailService and FileService subscribe to those events. But that seems like a very loose implementation - and what happens if the services fail? Please let me know what you think is the right solution here.
2. A song is purchased from a digital music store. The shopping cart is emptied. The purchase is persisted. The payment service is called. An email confirmation is sent.
Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction? Of course I could put everything in the MVC controller with injected services. But if I want real DDD all business logic should be in the domain. But which entity should have the "Purchase" method? Song.Purchase()? Order.Purchase()? OrderProcessor.Purchase() (domain service)? ShoppingCartService.Purchase() (application service?)
This is a case where I think it's very hard to use real business logic inside the domain entities. If it's not good practice to inject anything into the entities, how can they ever do other stuff than checking its own (and its aggregate's) state?
I hope these examples are clear enough to show the issues I'm dealing with.
Dimitry's answer points out some good things to look for. Often/easily you find yourself in your scenario, with a data shoveling from db up to GUI through different layers.
I have been inspired by Jimmy Nilsson's simple advice "Value objects, Value objects and more Value objects". Often people tend to focus to much on Nouns and model them as entity. Naturally you often having trouble in finding DDD behavior. Verbs are easier to associate with behavior. A good thing is to make these Verbs appear in your domain as Value objects.
Some guidance I use for my self when trying to develop the domain (must say that it takes time to construct a rich domain, often several refactoring iterations...) :
Minimize properties (get/set)
Use value objects as much as you can
Expose as little you can. Make you domain aggregates methods intuitive.
Don't forget that your Domain can be rich by doing Validation. It's only your domain that knows how to conduct a purchase, and what's required.
Your domain should also be responsible for validation when your entities make a transition from one state two another state (work flow validations).
I'll give you some examples:
Here is a article I wrote on my blog regarding your issue about anemic Domain http://magnusbackeus.wordpress.com/2011/05/31/preventing-anemic-domain-model-where-is-my-model-behaviour/
I can also really recommend Jimmy Bogard's blog article about entity validations and using Validator pattern together with extension methods. It gives you the freedom to validate infrastructural things without making your domain dirty:
http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/
I use Udi's Domain Events with great success. You can also make them asynchronous if you believe your service can fail. You also wrap it in a transaction (using NServiceBus framework).
In your first example (just brainstorming now to get our minds thinking more of value objects).
Your MusicService.AddSubscriber(User newUser) application service get a call from a presenter/controller/WCF with a new User.
The service already got IUserRepository and IMusicServiceRepository injected into ctor.
The music service "Spotify" is loaded through IMusicServiceRepository
entity musicService.SignUp(MusicServiceSubscriber newSubsriber) method takes a Value object MusicServiceSubscriber.
This Value object must take User and other mandatory objects in ctor
(value objects are immutable). Here you can also place logic/behavior like handle subscriptionId's etc.
What SignUp method also does, it fires a Domain Event NewSubscriberAddedToMusicService.
It get caught by EventHandler HandleNewSubscriberAddedToMusicServiceEvent which got IFileService and IEmailService injected into it's ctor. This handler's implementation is located in Application Service layer BUT the event is controlled by Domain and MusicService.SignUp. This means the Domain is in control. Eventhandler creates file and sends email.
You can persist the user through eventhandler OR make the MusicService.AddSubscriber(...) method to this. Both will do this through IUserRepository but It's a matter of taste and perhaps how it will reflect the actual domain.
Finally... I hope you grasp something of the above... anyhow. Most important is to start adding "Verbs" methods to entitys and making the collaborate. You can also have object in your domain that are not persisted, they are only there for mediate between several domain entities and can host algorithms etc.
A user signs up for a service. The user is persisted in the
database, a file is generated and saved (needed for the user account),
and a confirmation email is sent.
You can apply Dependency Inversion Principle here. Define a domain interface like this:
void ICanSendConfirmationEmail(EmailAddress address, ...)
or
void ICanNotifyUserOfSuccessfulRegistration(EmailAddress address, ...)
Interface can be used by other domain classes. Implement this interface in infrastructure layer, using real SMTP classes. Inject this implementation on application startup. This way you stated business intent in domain code and your domain logic does not have direct reference to SMTP infrastructure. The key here is the name of the interface, it should be based on Ubiquitous Language.
A song is purchased from a digital music store. The shopping cart
is emptied. The purchase is persisted. The payment service is called.
An email confirmation is sent. Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction?
Use OOP best practices to assign responsibilities (GRASP and SOLID). Unit testing and refactoring will give you a design feedback. Orchestration itself can be part of thin Application Layer. From DDD Layered Architecture:
Application Layer: Defines the jobs the software is supposed to do and directs the
expressive domain objects to work out problems. The tasks this layer
is responsible for are meaningful to the business or necessary for
interaction with the application layers of other systems.
This layer is kept thin. It does not contain business rules or
knowledge, but only coordinates tasks and delegates work to
collaborations of domain objects in the next layer down. It does not
have state reflecting the business situation, but it can have state
that reflects the progress of a task for the user or the program.
Big part of you requests are related to object oriented design and responsibility assignment, you can think of GRASP Patterns and This, you can benefit from object oriented design books, recommend the following
Applying UML and Patterns

Resources