Interactions between Service, Model, and Repository Layers - domain-driven-design

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.

Related

DDD Layers and External Api

Recently I've been trying to make my web application use separated layers.
If I understand the concept correctly I've managed to extract:
Domain layer
This is where my core domain entities, aggregate roots, value objects reside in. I'm forcing myself to have pure domain model, meaning i do not have any service definitions here. The only thing i define here is the repositories, which is actually hidden because axon framework implements that for me automatically.
Infrastructure layer
This is where the axon implements the repository definitions for my aggregates in the domain layer
Projection layer
This is where the event handlers are implemented to project the data for the read model using MongoDB to persist it. It does not know anything other than event model (plain data classes in kotlin)
Application layer
This is where the confusion starts.
Controller layer
This is where I'm implementing the GraphQL/REST controllers, this controller layer is using the command and query model, meaning it has knowledge about the Domain Layer commands as well as the Projection Layer query model.
As I've mentioned the confusion starts with the application layer, let me explain it a bit with simplified example.
Considering I want a domain model to implement Pokemon fighting logic. I need to use PokemonAPI that would provide me data of the Pokemon names stats etc, this would be an external API i would use to get some data.
Let's say that i would have domain implemented like this:
(Keep in mind that I've stretched this implementation so it forces some issues that i have in my own domain)
Pokemon {
id: ID
}
PokemonFight {
id: ID
pokemon_1: ID
pokemon_2: ID
handle(cmd: Create) {
publish(PokemonFightCreated)
}
handle(cmd: ProvidePokemonStats) {
//providing the stats for the pokemons
publish(PokemonStatsProvided)
}
handle(cmd: Start) {
//fights only when the both pokemon stats were provided
publish(PokemonsFought)
}
The flow of data between layers would be like this.
User -> [HTTP] -> Controller -> [CommandGateway] -> (Application | Domain) -> [EventGateway] -> (Application | Domain)
Let's assume that two of pokemons are created and the use case of pokemon fight is basically that when it gets created the stats are provided and then when the stats are provided the fight automatically starts.
This use case logic can be solved by using event processor or even saga.
However as you see in the PokemonFight aggregate, there is [ProvidePokemonStats] command, which basically provides their stats, however my domain do not know how to get such data, this data is provided with the PokemonAPI.
This confuses me a bit because the use case would need to be implemented on both layers, the application (so it provides the stats using the external api) and also in the domain? the domain use case would just use purely domain concepts. But shouldn't i have one place for the use cases?
If i think about it, the only purpose saga/event processor that lives in the application layer is to provide proper data to my domain, so it can continue with it's use cases. So when external API fails, i send command to the domain and then it can decide what to do.
For example i could just put every saga / event processor in the application, so when i decide to change some automation flow i exactly know what module i need to edit and where to find it.
The other confusion is where i have multiple domains, and i want to create use case that uses many of them and connects the data between them, it immediately rings in my brain that this should be application layer that would use domain APIs to control the use case, because I don't think that i should add dependency of different domain in the core one.
TL;DR
What layer should be responsible of implementing the automated process between aggregates (can be single but you know what i mean) if the process requires some external API data.
What layer should be responsible of implementing the automated process between aggregates that live in different domains / micro services.
Thank you in advance, and I'm also sorry if what I've wrote sounds confusing or it's too much of text, however any answers about layering the DDD applications and proper locations of the components i would highly appreciate.
I will try to put it clear. If you use CQRS:
In the Write Side (commands): The application services are the command handlers. A cmd handler accesses the domain (repositories, aggreagates, etc) in order to implement a use case.
If the use case needs to access data from another bounded context (microservice), it uses an infraestructure service (via dependency injection). You define the infraestructure service interface in the application service layer, and the implementation in the infra layer. The infra then access the remote microservice via http rest for example. Or integration through events.
In the Read Side (queries): The application service is the query method (I think you call it projection), which access the database directly. There's no domain here.
Hope it helps.
I do agree your wording might be a bit vague, but a couple of things do pop up in my mind which might steer you in the right direction.
Mind you, the wording makes it so that I am not 100% sure whether this is what you're looking for. If it isn't, please comment and correct my on the answer I'll provide, so I can update it accordingly.
Now, before your actual question, I'd firstly like to point out the following.
What I am guessing you're mixing is the notion of the Messages and your Domain Model belonging to the same layer. To me personally, the Messages (aka your Commands, Events and Queries) are your public API. They are the language your application speaks, so should be freely sharable with any component and/or service within your Bounded Context.
As such, any component in your 'application layer' contained in the same Bounded Context should be allowed to be aware of this public API. The one in charge of the API will be your Domain Model, that's true, but these concepts have to be shared to be able to communicate with one another.
That said, the component which will provide the states to your aggregate can be viewed from two directions I think.
It's a component that handles a specific 'Start Pokemon Match' Command. This component has the smarts to know to firstly retrieve the states prior to being able to dispatch a Create and ProvidePokemonStats command, thus ensuring it'll consistently create a working match with the stats in it by not dispatching any of both of the external stats-retrieval API fails.
Your angle in the question is to have an Event Handling Component that reacts on the creation of a Match. From here, I'd state a short-lived saga would be in place, as you'd need to deal with the fault scenario of not being able to retrieve the stats. A regular Event Handler is likely to lean to deal with this correctly.
Regardless of the two options you select, this service will deal with messages, a.k.a. your public API. As such it's within your application and not a component others will deal with directly, ever.
When it comes to your second question, I feel the some notion still holds. Two distinct applications/microservices only more so suggests your talking about two different Bounded Contexts. Certainly then a Saga would be in place to coordinate the operations between both contexts. Note that between Bounded Contexts, you want to share consciously when it comes to the public API, as you'd ideally not expose everything to the outside world.
Hope this helps you out and if not, like I said, please comment and provide me guidance how to answer your question properly.

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.

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.

Resources