After reading Eric Evans' Domain driven Design I have a few questions. I searched but no where i could able to find satisfying answers. Please let me know if anyone of you have clear understanding below questions.
My concerns are
Repository is for getting already existing aggregates from DB,Web service .
If yes, Can Repository also have transaction calls on this entity (i.e Transfer amount,send account details ...etc)
Can Entity have Methods which have business logic in which it calls infrastructure Layer services for sending emails .. logs etc (Entity methods calling IS services direclty).
Repository implementation and Factory classes will reside in Infrastrucure Layer. is that correct statement ?
Can UI layer (controller) call Repositry methods directly ? or should we call these from Application layer ?
There are still lot many confusion in my mind ... please guide me ...
Books i am using Eric Evan's domain driven desing ......
.NET Domain-Driven Design with C#
There is a lot of debate about whether Repositories should be read-only or allow transactions. DDD doesn't dictate any of these views. You can do both. Proponents of read-only Repositories prefer Unit of Work for all CUD operations.
Most people (self included) consider it good practice that Entities are Persistent-Ignorant. Extending that principle a bit would indicate that they should be self-contained and free of all infrastructure layer services - even in abstract form. So I would say that calls to infrastructure services belong in Service classes that operate on Entities.
It sounds correct that Repository implementations and Factories (if any) should reside in the infrastructure layer. Their interfaces, however, must reside in the Domain Layer so that the domain services can interact with them without having dependencies on the infrastructure layer.
DDD doesn't really dictate whether you can skip layers or not. Late in the book, Evans talks a bit about layering and calls it Relaxed Layering when you allow this, so I guess he just sees it as one option among several. Personally I'd prefer to prevent layer skipping, because it makes it easier to inject some behavior at a future time if calls already go through the correct layers.
Personally, in my latest DDD-project, I use a Unit Of Work that holds an NHibernate session. The UoW is ctor injected in the repositories, giving them the single responsible of Add, Remove and Find.
Evans has stated that one piece of the puzzle that's missing in the DDD book is «Domain Events». Using something like Udi Dahan's DomainEvents will give you a totally decoupled architecture (the domain object simply raises an event). Personally, I use a modified version of Domain Events and StructureMap for the wiring. It works great for my needs.
I recommend, based on other recommendations, that the Repository interfaces be a part of the model, and their implementations be a part of the infrastructure.
Yes! I've personally worked on three DDD web projects where services and repositories were injected to the presenters/controllers (ASP.NET/ASP.NET MVC) and it made a lot of sense in our context.
The repository should only be for locating and saving entities, there should not be any business logic in that layer. For example:
repository.TransferAmount(amount, toAccount); // this is bad
Entities can do things like send emails as long as they depend on abstractions defined in your domain. The implementation should be in your infrastructure layer.
Yes, you put your repository implementation in your infrastructure layer.
Can UI layer (controller) call Repositry methods directly ? or should we call these from Application layer ?
Yes, I try to follow this pattern for the most part:
[UnitOfWork]
public ActionResult MyControllerAction(int id)
{
var entity = repository.FindById(id);
entity.DoSomeBusinessLogic();
repository.Update(entity);
}
Related
In my application a few layers.
In this topic will focus on Domain and Infrastructure layers.
I have repository interface ClientRepositoryInterface in Domain layer.
And I have implementation of this interface ClientRepositoryImpl in Infrastructure layer.
But to reconstitute the object in the middle of the cycle of its existence I need factory(ReconstitutionClientFactory).
Call the factory will be in the repository.
The book by Eric Evans is described as a normal practice.
But where this factory(ReconstitutionClientFactory) should be located? In Domain or in Infrastructure layer?
I think in Domain...
BUT! But then the lower layer will directly call a higher layer!
This is wrong, but how to do right?
Factory & Repository Concepts
To answer your question, I think it's important to focus on responsibilities of the concepts defined by DDD.
In the blue book, there is a section that deals with the problem that you describe:
A FACTORY handles the beginning of an object’s life; a REPOSITORY helps manage the middle and the end.
and specifically for your question:
Because the REPOSITORY is, in this case, creating objects based on data, many people consider the REPOSITORY to be a FACTORY—indeed it is, from a technical point of view.
(both quotes from Evans, chapter 6, section "The relationship with factories")
To keep the concepts pure, it is important that the interface of your factories and repositories are clean. So don't allow creating new business objects through the repository interface, and don't allow querying existing ones through the factory interface.
Keeping the interfaces clean does however not mean that you should not use a factory from the repository implementation, because, after all, the repository creates an instance at some point, and if that instance creation is complex, a factory is the appropriate solution.
To quote Evans again:
Whenever there is exposed complexity in reconstituting an object from another medium, the FACTORY is a good option.
Note, however, that the repository will most likely call a different method on the factory than the clients that really want to create a new domain object (as opposed to reconstitution).
There is even an example in Evans' book that illustrates approach:
Answer to your question
Now that it is clear that this is allowed, lets focus on your question of where to put the factory:
The DDD factory interface belongs in the domain, because your domain logic uses this to create domain objects.
The DDD reconstitution factory interface does not belong in the domain, since this is only relevant for your repository. It does not exist in the real world of your domain.
Now if you're using an architecture that prohibits dependencies from the domain to the infrastructure (which you probably should when applying DDD), it's clear that the factory implementation belongs in the infrastructure. Note that it does not matter whether you call your layers layers, rings, realms or whatever, the dependencies are the important part.
First of all, the layers approach is kinda obsolete. When talking layers think 'context', who's on top of who isn't important.
The repository is in charge of restoring an object. A factory just creates a new object. Note the different semantics. The repository knows how saving/restoring to/from persistence is done and that depends on the storage and the method of access.
So, everything is done inside the repository i.e in the Infrastructure. If you serialize things, then you need just to deserialize back (this is how a document db does things anyway). If you're using an ORM or store things in tables then you'll do all the query required to get the data and repopulate the object. An ORM is the easiest way since it can use reflection to populate private properties. In this case the ORM itself is the factory.
One more thing, restoring, while technically can be done by a domain factory, it isn't the factory's purpose to do that because it breaks the layer boundaries. We want to keep everything persistence related in the Infrastructure.
Probably similar questions have been asked many times but I think that every response helps to make the understanding of DDD better and better. I would like to describe how I perceive certain aspects of DDD. I have some basic uncertainties around it and would appreciate if someone could give a solid and practical anwser. Please note, these questions assume a 'classic' approach to DDD. This means using ORM's etc. Approaches like CQRS and event sourcing are not considered here.
Aggregates and entities are the primary objects that implement domain logic. They have state and identity. In this context, I perceive domain logic as the set of all commands that mutate that state. Does that make sense? Why is domain logic related exclusively to state? Is it legal to model domain objects that have no identitiy or no state? Why can't a domain object be implemented as a transaction script? Example: Consider an object that recommends you a partner for a dating site. That object has no real state, but it does quite a lot of domain logic? Putting that into the service layer implies that the domain model cannot cover all logic.
Access to other domain objects. Can aggregates have access to a repository? Example: When a (stateful) domain object needs to have access to all 'users' of the system to perform its work, it would need access them via the repository. As a consequence, an ORM would need to inject the repository when loading the object (which might be technically more challenging). If objects can't have access to repositories, where would you put the domain logic for this example? In the service layer? Isn't the service layer supposed to have no logic?
Aggregates and entities should not talk to the outside world, they are only concerned about their bounded context. We should not inject external dependencies (like IPaymentGateway or IEmailService) into a domain object, this would cause the domain to handle exceptions that come from outside. Solution: an event based approach. How do you send events then? You still need to inject the correct 'listeners' every time you instantiate a domain object. ORM's are about restoring 'data' but are not primarly intended to inject dependencies. Do we need an DI-ORM mix?
Domain objects and DTO's. When you query an aggregate root for its state does it return a projection of its state (DTO) or the domain objects themselves? In most models that I see, clients have full access to the domain data model, introducing a deep coupling to the actual structure of the domain. I perceive the 'object graph' behind an aggregate to be its own buisness. That's encapsulation, right? So for me an aggregate root should return only DTO's. DTO's are often defined in the service layer but my approach is to model it in the domain itself. The service layer might still add another level of abstraction, but that's a different choice. Is that a good advice?
Repositories handle all CRUD operations at the aggregate root level. What about other queries? Queries return DTO's and not domain objects. For that to work, the repsitory must be aware of the data structure of the domain which introduces a coupling. My advice is similar to before: Use events to populate views. Thus, the internal structure is not made public, only the events carry the necessary data to build up the view.
Unit of work. A controller at the system boundary will instantiate commands and pass them to a service layer which in turn loads the appropriate aggregates and forwards the commands. The controller might use multiple commands and pass them to multiple services. This is all controlled by the unit of work pattern. This means, repositories, entities, services - all participate in the same transaction. Do you agree?
Buisness logic is not domain logic. From a buisness perspective the realization of a use case might involve many steps: Registering a customer, sending an email, create a storage account, etc. This overall process can impossibly fit in a domain aggregate root. The domain object would need to have access to all kind of infrastructure. Solution: Workflows or sagas (or transaction script). Is that a good advice?
Thank you
The first best practice I can suggest is to read the Evans' book. Twice.
Too many "DDD projects" fail because developers pretend that DDD is simply OOP done right.
Then, you should really understand that DDD is for applications that have to handle very complex business rules correctly. In a nutshell: if you don't need to pay a domain expert to understand the business, you don't need DDD. The core concept of DDD, indeed, is the ubiquitous language that both the coders, the experts and the users share to understand each other.
Furthermore, you should read and understand what aggregates are (consistency boundaries) by reading Effective Aggregate Design by Vernon.
Finally, you might find useful the modeling patterns documented here.
Despite my comment above, I took a stab at your points. (note: I'm not Eric Evans or Jimmy Nilsson so take my "advice" with a grain of salt).
Your example "Consider an object that recommends you a partner for a dating site.", belongs in a Domain service (not an infrastructure service). See this article here - http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/
Aggregates do not access repositories directly, but they can create a unit of work which combines operations from multiple domain objects into one.
Not sure on this one. This should really be a question by itself.
That's debatable, in theory, the domain entities would not be directly available outside the aggregate root, but that is not always practical. I consider this decision on a case-by-case basis.
I not sure what you mean exactly by "queries". If modeling all possible "reading" scenarios in your domain does not seem practical or provide sufficient performance, it suggests a CQRS solution is probably best.
Yes, I agree. UOW is a tool in your toolbox that you can use in various layers.
This statement is fundamentally wrong "Business logic is not domain logic". The domain IS the representation business logic, thus one reason for using ubiquitous language.
I am getting my feet wet with DDD (in .Net) for the first time, as I am re-architecting some core components of a legacy enterprise application.
Something I want to clear up is, how do we implement persistence in a proper DDD architecture?
I realize that the domains themselves are persistence ignorant, and should be designed using the "ubiquitous language" and certainly not forced into the constraints of the DAC of the month or even the physical database.
Am I correct that the Repository Interfaces live within the Domain assembly, but the Respository Implementations exist within the persistence layer? The persistence layer contains a reference to the Domain layer, never vice versa?
Where are my actual repository methods (CRUD) being called from?
Am I correct that the Repository Interfaces live within the Domain
assembly, but the Repository Implementations exist within the
persistence layer? The persistence layer contains a reference to the
Domain layer, never vice versa?
Yes, this is a very good approach.
Where are my actual repository methods (CRUD) being called from?
It might be a good idea to not think in CRUD terms because it is too data-centric and may lead you into Generic Repository Trap. Repository helps to manage middle and the end of life for domain objects. Factories are often responsible for beginning. Keep in mind that when the object is restored from the database it is in its midlife stage from DDD perspective. This is how the code can look like:
// beginning
Customer preferredCustomer = CustomerFactory.CreatePreferred();
customersRepository.Add(preferredCustomer);
// middle life
IList<Customer> valuedCustomers = customersRepository.FindPrefered();
// end life
customersRepository.Archive(customer);
You can call this code directly from you application. It maybe worth downloading and looking at Evan's DDD Sample. Unit of Work pattern is usually employed to deal with transactions and abstracting your ORM of choice.
Check out what Steve Bohlen has to say on the subject. The code for the presentation can be found here.
I was at the presentation and found the information on how to model repositories good.
Am I correct that the Repository Interfaces live within the Domain
assembly, but the Repository Implementations exist within the
persistence layer? The persistence layer contains a reference to the
Domain layer, never vice versa?
I disagree here, let's say a system is comprised of the following layers:
Presentation Layer (win forms, web forms, asp.net MVC, WPF, php, qt, java, , ios, android, etc.)
Business Layer (sometimes called managers or services, logic goes here)
Resource Access Layer (manually or ORM)
Resource/Storage (RDBMS, NoSQL, etc.)
The assumption here is that the higher you are the more volatile the layer is (highest being presentation and lowest being resource/storage). It is because of this that you don't want the resource access layer referencing the business layer, it is the other way around! The business layer references the resource access layer, you call DOWN not UP!
You put the interfaces/contracts in their own assembly instead, they have no purpose in the business layer at all.
I'm looking for clarification on the following 2 points with regards to DDD.
1.Can a domain entity call a repository?
2.Can a domain service call a repository?
Thanks
Edit
Found a suite of documents that detailed the DDD layers in lots of detail and this is what it said;
Additionally, and although as a rule Repositories are only used from the Application layer, it is also possible to make exceptions, and make queries invoking Repositories from the Domain services as necessary. But this should be avoided as much as possible in order to achieve homogeneity in our developments.
I wouldn't design a domain entity to reference a repository. A "repository" is rarely a part of the domain and would introduce a technical concern into your domain model. I've found repositories to fit best at the application services layer.
I'm not aware of such hard and fast rules. Anything can be done.
But here's how I do it. I don't know if it qualifies as DDD:
Usually domain objects do not call repositories. They need not be aware whether they are persisted or not.
Services orchestrate domain objects and repositories to fulfill use cases. They own units of work and manage transactions.
Which layer should the repository classes go in? Domain or Infrastructure?
The repository interfaces are part of the domain. The actual implementation of the interfaces should be part of the infrastructure.
Repository implementation classes, together with separate interfaces (if they exist) should go into the domain layer.
The reason is given by the fundamental rule to be followed in a layered architecture: a lower layer must not depend on a higher layer.
If we accept this rule (otherwise it's not a layered architecture), then putting repository implementations into the infrastructure layer would make it dependant on the domain layer, therefore violating the fundamental rule of layering.
For example, when we create a new domain entity, we put it in the domain layer; and since a repository (both its interface and its implementation) must inevitably depend on the domain entity, it means the repository must also go into the domain layer. Otherwise, we would be changing the infrastructure layer whenever a domain entity was added/removed/modified in the domain layer.
Other concerns, such as keeping the domain layer "clean" and independent of persistence details, can and should be achieved by using the appropriate infrastructure services from the implementations inside the domain layer. For example, in Java we can use JPA to implement repositories with very little code, and no SQL/JDBC or database-specific code (whether it's really a good idea to implement repositories with JPA is another discussion; in any case, JPA entities will make use of JPA annotations anyway).
References: Wikipedia,
MSDN
Repository classes implementations should be situated in the Infrastructural Layer. Repository interfaces should be in the Service Layer.
Domain Layer should know nothing about the repositories. Strategic patterns of DDD state that Domain Layer should always be in sync with conceptual model. That means that Domain Layer should translate well known domain processes to code and vice versa. And domain process is what your domain experts should know well. And domain experts know nothing about repositories.
Another way to think about it. Let us suppose we put repositories or the interfaces of repositories into a Domain Layer. I.e. now we have the repository concept in Domain Layer code. Also, the Domain Layer should be in sync with the conceptual model of domain. So, let us ask ourselves what is the representation of repository in the conceptual model. The correct answer is that there is no repository in the conceptual model. Hence, repository can not be in Domain Layer.
All said, I still come across projects which have repositories in the Domain Layer and engineers on the projects still call it a DDD practice. I assume the problem here is that people do not pay a lot of attention to strategic patterns which lie at the heart of DDD, but just play around with the tactical patterns which may simplify coding efforts a bit.
I guess that depends how You are going to rely on them.
Question is - are You going to allow Yourself to use repositories from inside of domain?
If so - then You are forced to put them in.
I myself like to put them outside of domain. So - typical life cycle of something looks like this =>
UI => Controller => retrieve aggregate root from repo => call logic through aggregate root => if new aggregate root created, add it to repo.
Sometimes controller calls application service that does some additional stuff besides just retrieving root and calling function on it. But idea is same - domain knows nothing about persistence.
While (as I see it) there's nothing wrong with putting repos in domain (or at least abstractions of them), it makes Your domain more aware of persistence. Sometimes that can solve problems, but generally - that will definitely make Your domain more complex.
Use what seems more natural for You and be ready to switch Your ways any time.