DDD - Entity DTO representation on Repositories - domain-driven-design

There are some properties that makes no sense for the domain but are essential for the repository, one example being the partition key.
Is it ok to have a DTO on my repository that will extend the base implementation of the entity, adding the relevant fields?

That is totally ok. As long as this DTO stays in the repository.
In Fowler's PoEAA:
the Repository pattern is described as: Mediates between the domain
and data mapping layers using a collection-like interface for
accessing domain objects.
As long as the repository is doing his job correctly (storing and fetching domain models) the implementation doesn't matter.
Just make sure that whatever implementation details of the repository doesn't get propagated in the rest of the project. If you add a DTO to your entity inside of the repository make sure you return the entity without the DTO or other irrelevant extra fields.

Related

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.

What types of code are appropriate for the service layer?

Assume you have entities, a service layer, and repositories (with an ORM like NHibernate). The UIs interact with the service layer.
What types of code are appropriate for the service layer?
Repository Coordination?
It looks like entities should not reference the repository so should calls for loading/saving/evicting entities exist in the service layer?
Business Logic that Involves Repositories?
If the above is true, should something like checking if a username is distinct go in the service layer (i.e. call GetUsersByUsername and check the results)? Before suggesting that the DB should handle distinct, what about verifying that a password hasn't been used in 90 days?
Business Logic that Involves Multiple Entities?
I'm not sure about this one, but say you have the need to apply an operation against a collection of entities that may or may not be related and is not really applicable to a single entity. Should entities be capable of operating on these collections or does this sort of thing belong in the service layer?
Mapping?
Whether you use DTOs or send your entities to/from your service layer, you will likely end up mapping (preferably with AutoMapper). Does this belong in the service layer?
I'm looking for confirmation (or rejection) of the ideas listed above as well as any other thoughts about the responsibilities of a service layer when working with entities/repositories.
Repository Coordination?
Aggregate roots should draw transactional boundaries. Therefore - multiple repositories should rarely be involved. If they are - that usually happens when You are creating new aggregate root (as opposed to modifying its state).
Business Logic that Involves Repositories?
Yes, checking if username is distinct might live in service layer. Because User usually is an aggregate root and aggregate roots live in global context (there is nothing that "holds" them). I personally put that kind of logic in repository or just check directly through ORM.
As for checking password usage - that's a concern of user itself and should live underneath User object. Something like this:
class User{
void Login(){
LoggedOn=DateTime.Now;
...
}
bool HasLoggedInLast90Days(){
return (DateTime.Now-LoggedOn).Days<=90;
}
}
Business Logic that Involves Multiple Entities?
Aggregate root should manage their entity collections.
class Customer{
void OrderProduct(Product product){
Orders.Add(new Order(product)); //<--
}
}
But remember that aggregate root should not micro-control its entities.
E.g. this is bad:
class Customer{
void IsOrderOverdue(Order order){
return Orders.First(o=>o==order)....==...;
}
}
Instead use:
class Order{
void IsOverdue(){
return ...;
}
}
Mapping?
I suppose mapping to dto`s live in service layer. My mapping classes lives next to view model classes in web project.

Persistence encapsulated via the domain, or persistence via the Repository?

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.

DDD: Where to keep domain Interfaces, the Infrastructure?

Does it make sense to group all Interfaces of your Domain Layer (Modules, Models, Entities, Domain Services, etc) all within the Infrastructure layer? If not, does it make sense to create a "shared" project/component that groups all of these into a shared library? After all, the definition of "Infrastructure Layer" includes "shared libraries for Domain, Application, and UI layers".
I am thinking of designing my codebase around the DDD layers: UI, Application, Domain, Infrastructure. This would create 4 projects respectfully. My point is, you reference the Infrastructure Layer from the Domain Layer. But if you define the interfaces in the Domain Layer project, say for IPost, then you'll have a circulur reference when you have to reference the Domain Layer project from the Infrastructure project when you are defining the IPostRepository.Save(IPost post) method. Hence, the idea of "define all Interfaces in the Shared library".
Perhaps the repositories should not expect an object to save (IPostRepository.Save(IPost post); but instead, expect the params of the object (that could be a long set of params in the Save() though). Given, this could be an ideal situation that shows when an object is getting overly complex, and additional Value Objects should be looked into for it.
Thoughts?
Concerning where to put the repositories, personally I always put the repositories in a dedicated infrastructure layer (e.g . MyApp.Data.Oracle) but declare the interfaces to which the repositories have to conform to in the domain layer.
In my projects the Application Layer has to access the Domain and Infrastructure layer because it’s responsible to configure the domain and infrastructure layer.
The application layer is responsible to inject the proper infrastructure into the domain. The domain doesn’t know to which infrastructure it’s talking to, it only knows how to call it. Of course I use IOC containers like Structuremap to inject the dependencies into the domain.
Again I do not state that this is the way DDD recommends to structure your projects, it’s just the way, I architecture my apps.
Cheers.
I’m quiet new in DDD so don’t hesitate to comment if you disagree, as you I’m here to learn.
Personally I don’t understand why you should reference the infrastructure layer from your domain. In my opinion the domain shouldn’t be dependent on the infrastructure. The Domain objects should be completely ignorant on which database they are running on or which type of mail server is used to send mails. By abstracting the domain from the infrastructure it is easier to reuse; because the domain don’t know on which infrastructure its running.
What I do in my code is reference the domain layer from my infrastructure layer (but not the opposite). Repositories know the domain objects because their role is to preserve state for the domain. My repositories contains my basic CRUD operations for my root aggregates (get(id), getall(), save(object), delete(object) and are called from within my controllers.
What I did on my last project (my approach isn’t purely DDD but it worked pretty well) is that I abstracted my Repositories with interfaces. The root aggregates had to be instantiated by passing a concrete type of a Repository:
The root aggregate had to be instantiated through a repository by using the Get(ID) or a Create() method of the repository. The concrete Repository constructing the object passed itself so that the aggregate could preserve his state and the state of his child objects but without knowing anything of the concrete implementation of the repository.
e.g.:
public class PostRepository:IPostRepository
{
...
public Post Create()
{
Post post=new Post(this);
dbContext.PostTable.Insert(post);
return post;
}
public Save(post)
{
Post exitingPost=GetPost(post.ID);
existingPost = post;
dbContext.SubmitChanges();
}
}
public class Post
{
private IPostRepository _repository
internal Post(IPostRepository repository)
{
_repository = repository;
}
...
Public Save()
{
_repository.Save(this);
}
}
I would advise you to consider Onion architecture. It fits with DDD very nicely. The idea is that your repository interfaces sit in a layer just outside Domain and reference Entities directly:
IPostRepository.Save(Post post)
Domain does not need to know about repositories at all.
Infrastructure layer is not referenced by Domain, or anybody else and contains concrete implementations of repositories among other I/O-related stuff. The common library with various helpers is called Application Core in this case, and it can be referenced by anyone.

Data Transfer Objects, Domain Objects and Repositories

I'm trying to figure out how all these work together. I know that a DTO is basically just a container of data for the Domain Objects to pass back and forth to forms and such. Does the Domain object contain a DTO or do the DTO and the Domain Object happen to just have all of the same properties that will be mapped manually?
If I am exposing my DTO type in a service, how do I use the getters and setters without creating a round trip for each get/set operation on the client? I know that you can have one long constructor, but that can get ugly if you have more than 7 properties.
When implementing the Repository pattern, do I pass in the DTO or the Domain Object?
The DTO's and the Domain objects should be separate.
There should be a mapper that maps a DTO to a domain object and a domain object to a DTO. This mapper should be an implementation of an interface, with the default mapper using reflection to map the objects to each other.
The repository should be a service that returns the domain objects, which themselves should services.
If the DTO is a class that is exposed by a web service, the WSDL that is created defines the property as an element, and the proxy that gets created on the other side just creates a getter / setter property that is run on the client itself, so the getters and setters do not cause a roundtrip.
Even if you just create a public variable in your DTO, the proxy will be implemented as a getter and setter.
I think it's better to have the DTO contain a reference to the Domain object so that the DTO's consumers can begin using the Domain object. That said, if the DTO's consumers must not mutate the Domain object, you may need to have the DTO contain the values encapsulated in the Domain object. This can be difficult since you may need to do a deep copy of the Domain object.
I'm not sure why it's a problem that exposing a DTO type as a service would cause use of its getters/setters to do a round trip. If the service is a remote service, the returned DTO is serialized anyway and your getters/setters will get the copy of the values. If the service is not remote, it doesn't seem to be much of penalty to do a "round trip" since the client and the service are in the same process space.

Resources