Can the domain model and the repositories be in separate dlls?
In a 3 tier architecture I guess I would put the domain model in the business layer
and the repositories in the data access layer.
I get confused as it is my understanding that the domain model uses the repositories while the repositories should return objects from the domain model, which would cause a circular dependency.
I must be misunderstanding one or more of the above concepts.
Any clarification would be greatly appreciated as this has been bothering me for a while, thanks.
I don't think you should let your domain assembly reference anything from your own application at all. It should be the innermost assembly, that is totally ignorant of anything on the outside. It just sits there and knows the domain logic.
Your domain model shouldn't be using the repositories, the application services should.
(If the domain entities actually needs to use a repository, it should be injected from the application services. Some people would argue, that this should not be necessary though - and I think so too).
Try looking at it this way: Your have an application service which is the primary way your client/frontend/controller can use the domain. The application services defines the operations that can be done on your application.
The application service use a repository to load the domain object that it needs to work on, call the necessary method on the domain object and returns the result (if the operations return a such). The domain know nothing about the application service or the repository.
A nice way to get started organizing your application this way, is taking a look at this series of blog posts: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
And take a look at dependency injection, it can help you solve other problems, where it seems like, you would have a circular reference.
Ask if you have any questions.
Related
When using MVC5 I add a domain layer and storage layer using dependency injection for all the business data. But I have always left the ApplicationDbContext in the main MVC application layer project.
I've read a great many posts on SO and see many people recommend moving the ApplicationDbContext out of the MVC project. I'd like to understand why ApplicationDbContext should or should not be moved. Are there any reasons to not move this context?
On the one hand, ApplicationDbContext uses a data model which suggests it should be moved to the storage layer but that will require large DTO's. On the other hand, ApplicationDbContext really relates primarily to application access and I have a separate roles/permissions functionality for the business data anyway. Several SO posts also suggested checking roles in the application layer, not the domain layer, but that seems suspect; don't we want to check business roles in the domain layer?
So I'm confused and before I go to the work to move the ApplicationDbContext to a different layer, I'd like to make sure I'm making a sound and informed decision.
It is not a must, but it is advisable if you are doing DDD and your project tends to grow large.
Although DDD is not about implementation details, DDD asks for a clear separation of concerns. Then you should separate domain logic from infrastructure.
You could achieve that separation in many ways. One way would be to have a single project with folders for Domain, Application and Infrastructure, and have your DbContext reside in the Infrastructure folder. This is suitable for small projects.
In large projects, however, I would recommend you to evaluate the Clean Architecture, which will take this separation to project level.
I'd like to understand why ApplicationDbContext should or should not be moved. Are there any reasons to not move this context?
It can be moved, there's no rule against it. But the tooling will then require you to specify both startup and database projects as parameters, like this:
dotnet ef database update --project <path> --startup-project <path>
But since you're using MVC5, you're probably not using EF Core. In case of EF 6 or lower, you'll be using the Package Manager Console (PMC) to manage migrations and database-updates, which will make your life easier in that regard, since you can mark you MVC project as the Startup Project from the context menu, and select the target project from a dropdown control in the PMC.
Several SO posts also suggested checking roles in the application layer, not the domain layer, but that seems suspect; don't we want to check business roles in the domain layer?
Yes, roles are related to permissions, which are business rules. People probably recommend checking that in the application layer because you need to pull this data from the database, but you could do it like this:
Use the Specification Pattern to represent roles and permissions as an specification in the Domain Layer. But the IRepository interfaces would best be defined in Application Layer, as they represent infrastructure (which will be concretely implemented in the Infrastructure Layer). So you would start the role-checking in the Application Layer by using repositories to retrieve data, but the actual permission validation would be done by an Specification in the Domain Layer.
That would be one way to do it.
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.
I have a system that talks with the database using repositories. What is the correct definition when it is a remote service? Or better,
Repository is for databases as [...] is for external Web-Services.
I found in many places about ServiceAgents but I don't know if this is the correct definition.
In DDD, Repositories represent a virtual collection of entities (aggregate roots in particular). So, if you have 10M persisted customers, you would work with a repository as if it were a collection of all 10M in memory. Repositories generally only deal with the same types of operations you would find on a collection: Add something, Remove something, Find something in the collection.
If the actual persistence of the data occurs via a Web Service, the implementation of the repository might interact with a Web Service proxy rather than with a database. The fact that the persistence involves a web service doesn't drive how it should be expressed by your domain however. That is to say, whether the data is persisted via direct database calls, an ORM, a Web Service, or a courier pigeon is an implementation detail.
Now, if your domain model has dependencies to be facilitated by external services (e.g. credit card validation, address verification, etc.), this should be expressed as a Domain Service in the form of an interface which defines the required operations in terms of the domain model. To be clear, Domain Services are operations which are logically part of your domain, but don't fit cleanly for some reason or another on a given entity or value object. Behavior facilitated by an external service is just one example of when you might use a Domain Service, so don't think of Domain Services as "the repository pattern for Web Services" or some such thing.
Not sure if this is the official term but I'd refer to this as a "Service Proxy".
I'm just begging to wrap my head around most of the DDD principles but my understanding is that Repositories are generally used to abstract databases but they could be used to wrap anything that behaves as persistent and/or queryable store. So in short I guess what I'm suggesting is that if your service behaves enough like a database then I don't see any problem with using a repository to abstract access to the entities that it deals with.
Otherwise, if the web service doesn't directly deal with data or behavior that is in your domain, then perhaps your case may be a candidate for an infrastructure level service in your application layer.
If anybody has any objections then please comment as I would like to know if I myself am misunderstanding the intended use of repositories.
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.
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);
}