Persistence encapsulated via the domain, or persistence via the Repository? - domain-driven-design

If my Domain Model is not supposed to know/care about the Repository, then how does some behaviour like .UpdateOrder(...), that encapsulates a CRUD-Update, interface with the Repository? Through a Domain Service?
Ok, then my Repository has an effective CRUD-Update that's used in conjunction with my .UpdateOrder(...). That's fine. But i don't want someone to use the Update method on the Repository, i want them to go through the behaviour on the Entity (use UpdateOrder() instead). I'd prefer that in likeness to the way my Domain Model satisfies invariants - by it's design (private set properties, etc) - my Repository not expose an alternate method to "updating"/persisting the Entity.
Is this simply a access modifier problem that is solved by me not having the Update method in the Repo public. Or is there a 'better' answer? Please help me DDD ninjas.

The strict sequence in DDD would be:
var entityRepository = MyServiceLocator.Get<IEntityRepository>();
var myEntity = entityRepository.Load(<some criteria>);
myEntity.Change(something);
entityRepository.Save(myEntity);
The repository is always responsible for detecting/persisting all of the changes within the entity.
(btw, I'm assuming that your entity is an aggregate root)

If your domain model doesn't include persistence, then it doesn't include the operation of storing something. If your entity is something from the domain model, then it has no business persisting itself.
You say:
That's fine. But i don't want someone
to use the Update method on the
Repository, i want them to go through
the behaviour on the Entity
But i think that's mistaken. Your domain objects have no more responsibility for persisting themselves than they do printing themselves, drawing themselves on screen, etc. Your domain class should not have a UpdateOrder method.
Now, you might not want to expose the raw repository (from your persistence implementation layer) to other code, but that just means wrapping it in something suitable. It sounds like you do have code that needs to talk about persistence, so figure out what level of discourse it needs to work at, and expose a suitable interface to it.

Related

Application service responsability vs optimized DTO's

I am feeling stuck in my MPA ABP app development between three principles that I believe are DDD ones :
Application service has not to be tied to a controller. I mean a controller doesn't have to use always only one application service. Because application service conception has not presentation in mind.
DTO has to fit the view needs to minimize HTTP data transfer. So sometimes we have to design one DTO class per entity/concept and per view.
Application services get and return always DTO's.
Now I have a view which follows the Master-Detail principle: select one entity in the Master part from an entity list loads entity details in the Details part by Ajax call. But the entity selection in Master part is made by Ajax-synchronized cascade of dropdown lists: ParentEntities > Entities.
What choice respects better DDD ?
Put GetAllParent(), GetAllEntities(parentId) and GetEntity(id) all in MyViewApplicationService, then my application service can return optimized DTO's for my view needs, but violates DDD principle,
Put each of theses three methods in different application services, isolated more "domain" in mind, but DTO's are domain-oriented, somewhat generic. So DTO's are not optimized.
Let the controller the responsability to map into a DTO that fits view needs, but it should not do that.
Application service has not to be tied to a controller. I mean a controller doesn't have to use always only one application service.
Because application service conception has not presentation in mind.
Application services are not tied to the client type, but to the client needings. They return the data that client needs, so in that sense application services has the client (presentation) in mind.
Application services get and return always DTO's.
Not always. There are alternatives to DTOs, as Vaughn Vernon says in his book Implementing DDD (page 512):
Mediator
Domain Payload Object
State Representations
Use Case optimal repository queries (closed to CQRS)
Data Transformers
What choice respects better DDD ?
Put GetAllParent(), GetAllEntities(parentId) and GetEntity(id) all in MyViewApplicationService, then my application service can return
optimized DTO's for my view needs, but violates DDD principle,
You shouldn't name the application service refering the client technology (MyView), but according to the functionality it offers.
Put each of theses three methods in different application services, isolated more "domain" in mind, but DTO's are
domain-oriented, somewhat generic. So DTO's are not optimized.
It doesn't matter if you put the 3 methods in just one service or you have one service for each method. The controller should call them anyway.
Let the controller the responsability to map into a DTO that fits view needs, but it should not do that.
If you mean the application service returns domain objects and the controller translates them to DTOs, then no, you shouldn't do that as you are exposing the domain to clients.
I understand your problem I think, let's start at the beginning:
...Put GetAllParent(), GetAllEntities(parentId) and GetEntity(id) all in MyViewApplicationService...
Which of those words would a business person understand? Are any of those words part of the ubiquitous language?
They are of course all purely technical, therefore should be detail and should not influence the architecture. Basically they would be in the wrong place, they should not be visible at all.
...but DTO's are domain-oriented, somewhat generic. So DTO's are not optimized...
DTOs should not be part of anything remotely object-oriented. However, you did not say you want object-orientation so let's not dwell on that.
Still, if your object is supposed to be domain-oriented, then how come it's unfit (not optimized) for the application that is written specifically for that domain?
I think the problem is that your "object" is actually modeling something different than the domain. It's likely modeling the database table or its records.
I mean, if you are showing a profile for a product, then your "object" should be ProductProfile, not the generic Product. Or ProductDetails, or ProductHeroImage, and so on. Those things are of the domain and likely mentioned in the requirements document too.
Let the controller the responsability to map into a DTO that fits view needs, but it should not do that.
Why should it not do that? If the purpose of your feature is to show some data to the user, then why is that not considered a "business function". I mean it should be literally the other way around. The "view" is the business function you want, and the database/repository/controller/service or whatever is "just" technology that should be just a detail and not visible in the architecture.
Disclaimer: I must admit these views are not what most projects do under DDD, but maybe you find some sense in it to question those projects more in the future.:)

Using IQueryable with repository pattern in DDD

I need an advice on DDD (Domain Driven Design) and implementation of Repository pattern and encapsulation.
To my understanding is that Repository pattern enables me to put all the database access logic in one place and abstract that logic from other parts of application.
On the other side there is orm (Nhibernate, EntityFramework...) with its support for Linq and IQueryable.
My toughts are:
1. If I am using repository then I should not use IQueryable as my return type bust instead use IEnumerable. Because if I use IQueryable then this would allow leaking database code to other application layers (IE would allow other devs to do queries in mvc controller where they don't belong).
But every controls use IQueryable to access data and does this because is easier.
If I use IQueryable as return type of my repository methods then:
- I allow other developers to do database querying in other layers of application (and I think this should not be possible)
- It will leak my domain entities (domain model) to other layers of applications (ie. User interface) but should not, instead DTO should be used.
My question is is IQueryable a good practice in DDD?
I would say it's not a good practice.
Ideally you should have some sort of application layer on top of your domain. If you expose your domain objects directly or through Query object, someone might actually modify it outside of your control.
Personally i like to think of IQueryable as an implementation detail, ideally my domain would not depend on it (in case i want to switch my storage technology it could be a problem).
Most often i'll end up using IQueryable internally inside my repositories implementation. What i usually end up with is implementing generic repository that has a FindBySpecification method, and then have specialized repositories for every Aggregate root that inherits from it. For example:
public interface IRepository<TEntity>
{
TEntity Get(Guid ID);
void Add(TEntity entity);
void Remove(TEntity entity);
void Detach(TEntity entity);
IEnumerable<TEntity> WithSpecification(ISpecification<TEntity> specification);
}
public interface IOrdersRepository : IRepository<Order>
{
IEnumerable<Order> GetCompletedOrdersForAllPreferedCustomers(DateTime orderCompletedAfter);
Order GetOrderBySomeOtherComplicatedMeans();
}
Another aproach is to design your application to follow the CQRS principle.
Then you can have your DomainModel doing it's magic on the command side, and create a readonly model of your data for your client on the query side.
This setup can become really elaborate depending on your requirements, but it can be as simple as two ORM models mapped to the same database (the one on the command side is mapping your domain entities, the one on the query sides maps to simple DTOs ).
Personally I do not feel that exposing EF entities by way of IQueryable across all layers is necessarily a bad thing. But this is just my own opinion. Others may not agree especially if you look at it on the encapsulation perspective. But generally the concept of loose-coupling is a trade-off between complexity and practical gain. By encapsulating IQueryable know that you will loose a lot of practical gain, like the ability to lazy-load for instance.
If your application layer is directly on top of your repository layer, I vote to use IEnnumerable instead of IQueryable. But if you have a service layer in the middle (which I personally prefer to contain all business logic so the repository layer can specialize with data access operations) then I will have the repository return IQueryable and have the service layer return IEnnumerable after it has performed its business logic from the IQueryable object returned by the repository.
These are just my own personal rules:
If you need to encapsulate EF, encapsulate it away only from the application layer. Otherwise, use it as excessively as you need on all layers. EF is very powerful, encapsulating it in the repository layer will make you lose a lot of its power
The application layer should be as thin as possible, it should not perform any further processing on the data it receives from the layer below it. It receives the list and it renders it, that's it.

In which layer should Specification Pattern objects be "new'ed up"?

So, I've looked at some posts about the Specification Pattern here, and haven't found an answer to this one yet.
My question is, in an n-layered architecture, where exactly should me Specifications get "newed" up?
I could put them in my Service Layer (aka, Application layer it's sometimes called... basically, something an .aspx code-behind would talk to), but I feel like by doing that, I'm letting business rules leak out of the Domain. If the Domain objects are accessed some other way (besides the Service Layer), the Domain objects cannot enforce their own business rules.
I could inject the Specification into my Model class via constructor injection. But again, this feels "wrong". I feel like the only thing that should be injected into Model classes are "services", like Caching, Logging, dirty-flag tracking, etc... And if you can avoid it, to use Aspects instead of littering the constructors of the Model classes with tons of service interfaces.
I could inject the Specification via method injection (sometimes referred to as "Double Dispatch"???), and explicitly have that method encapsulate the injected Specification to enforce its business rule.
Create a "Domain Services" class, which would take a Specification(s) via constructor injection, and then let the Service Layer use the Domain Service to coordinate the Domain object. This seems OK to me, as the rule enforced by the Specification is still in the "Domain", and the Domain Service class can be named very much like the Domain object it's coordinating. The thing here is I feel like I'm writing a LOT of classes and code, just to "properly" implement the Specification pattern.
Add to this, that the Specification in question requires a Repository in order to determine whether it's "satisfied" or not.
This could potentially cause performance problems, esp. if I use constructor injection b/c consuming code could call a property that perhaps wraps the Specification, and that, in turn is calling the database.
So any ideas/thoughts/links to articles?
Where is the best place to new up and use Specifications?
Short answer:
You use Specifications mainly in your Service Layer, so there.
Long answer:
First of all, there's two questions here:
Where should your specs live, and where should they be new'd up?
Just like your repository interfaces, your specs should live in the domain layer, as they are, after all, domain specific. There's a question on SO that discusses this on repository interfaces.
Where should they be new'd up though? Well, I use LinqSpecs on my repositories and mostly ever have three methods on my repository:
public interface ILinqSpecsRepository<T>
{
IEnumerable<T> FindAll(Specification<T> specification);
IEnumerable<T> FindAll<TRelated>(Specification<T> specification, Expression<Func<T, TRelated>> fetchExpression);
T FindOne(Specification<T> specification);
}
The rest of my queries are constructed in my service layer. That keeps the repositories from getting bloated with methods like GetUserByEmail, GetUserById, GetUserByStatus etc.
In my service, I new-up my specs and pass them to the FindAll or FindOne methods of my repository. For example:
public User GetUserByEmail(string email)
{
var withEmail = new UserByEmail(email); // the specification
return userRepository.FindOne(withEmail);
}
and here is the Specification:
public class UserByEmail : Specification<User>
{
private readonly string email;
public UserByEmail(string email)
{
this.email = email;
}
#region Overrides of Specification<User>
public override Expression<Func<User, bool>> IsSatisfiedBy()
{
return x => x.Email == email;
}
#endregion
}
So to answer your question, specs are new'd up in the service layer (in my book).
I feel like the only thing that should be injected into Model classes
are "services"
IMO you should not be injecting anything into domain entities.
Add to this, that the Specification in question requires a Repository
in order to determine whether it's "satisfied" or not.
That's a code smell. I would review your code there. A Specification should definitely not require a repository.
A specification is an implementation check of a business rule. It has to exist in the domain layer full stop.
Its hard to give specifics on how you do this as every codebase is different, but any business logic in my opinion needs to be in the domain layer and nowhere else. This business logic needs to be completely testable and coupled loosely from UI, database, external services and other non-domain dependencies. So I would definitely rule out 1, 2, and 3 above.
4 is an option, at least the specification will live in your domain layer. However the newing up of specifications depends really again on the implementation. We usually use depencency injection, hence the newing up of pretty much all of our objects is performed via an IOC container and corresponding bootstrapping code (i.e. we usually wire the application fluently). However we would never directly link business logic directly to e.g. UI model classes and the like. We usually have contours/boundaries between things such as UI and domain. We usually define domain service contracts, which can then be used by outside layers such as the UI etc.
Lastly, my answer is assuming that the system you are working on is at least some way complex. If it is a very simple system, domain driven design as a concept is probably too over the top. However some concepts such as testability, readibility, SoC etc should be respected regardless of the codebase in my opinion.

Interactions between Service, Model, and Repository Layers

I have been tasked with the undertaking of translating an application from SharePoint to .NET. I am concerned with doing it the right way, so I got an architecture book to read up on patterns and practices.
I've tried to model everything out using Domain Driven Design. I have a Model that represents my world, a Repository to store it in the database, and a Service layer to interact with UI (which is WebForms, because I have 0 experience in MVC and am already hardly treading water with this undertaking).
I am having difficulty grasping the correct way for the layers to interact. My understanding is that the Model should be the base of everything. It references nothing, other layers reference it.
Question 1: Is that right?
I'm getting really concerned with the Service Layer. I'm noticing that I'm developing a very anemic Model, for two reasons: 1, my Model doesn't reference Repository, so I can't store anything via the Model. 2, I am trying to do things as they happen (ie. I add an object to a list of objects, so I store it in the DB one at a time instead of all at once when the user is done adding the objects). So a lot of the work is being done between the Service and Rep layers, with the Model just being there and looking nice.
I'm starting to worry--I'm early in the development, but I am the one being looked at to be the architect of all this. I don't want a maintenance nightmare (I expect this application will be used for years). As always, time is a concern, and I have not been able to prepare/learn effectively. Any help would be swell. :-)
Model should be the base of everything. It references nothing, other layers reference it.
Question 1: Is that right?
The typical way to enforce separation between the domain model and the persistence system is to define repositories. Persistence however is not a part of the domain model.
Your models should call methods defined by the repository
For example consider this totally fake repository:
// Repository
public class SharepointRepository
{
void SaveWidget(); // Implement
}
So the repository is only concerned with loading and saving data, they don't contain any of your domain logic at all.
However if your model is tightly bound to the repository, you've got a separation of concerns issue.
So in this case, Dependency Injection becomes useful. With the prior example, your model would have to explicitly instantiate SharePointRepository and invoke methods. A cleaner way of doing this so that your model doesn't care is to inject the dependency of your repository at runtime.
namespace YourApp.Domain.Abstract
{
public interface ISharePointRepository
{
void SaveWidget();
}
}
Based on this interface, you could build a concrete implementation and inject the dependency to the concrete implementation at run time.
namespace YourApp.Domain.Concrete
{
public class SqlSharePointRepository : ISharePointRepository
{
void SaveWidget()
{
// Code that Saves the widget using the managed sql provider
}
}
}
So on your web form:
When you are collecting data, your model will be hydrated with data from the form, and will invoke a repository method, however the repository itself would have been injected into the asp.net application at runtime, so you could change SqlSharePointRepository to RavenDbRepository without breaking your app.
To see how to bind your repository in Webforms see this SO Post: How can I implement Ninject or DI on asp.net Web Forms?
With MVC the controller is responsible for the gap you think your are experiencing. But as to your questions and based on your current design, the model should invoke repository operations, however the repository itself should be loosely coupled.

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