As what I read from some articles on Domain Driven Design, the Domain Services are to ensure the logical integrity of the domain and may call other domain services for external things.
So, can I assume that, in a web application of separated front end and back end, even if the client side is not believable, as long as Domain Services can ensure that no business rule would be broken, I can put all Application Services to the front end?
If the answer is yes, is it reasonable that putting all Application Services to the front end would help reduce the load of the server and simplify the hierarchy (since the front end itself needs a service layer) for there would be no Application Service layer in the server side? Would there be security problems?
You can and you should keep the application layer as thin as possible and prevent any leaks of the domain model to the application layer. But I don't think that you can remove the application layer from the backend completly, because you need to have at least some persistence logic in there.
Related
I'm trying to learn Onion Architecture and as i understand, I've organized my solution as follows:
Domain
Domain.Entities (Business objects)
Domain.Interfaces (Interfaces for domain services and repositories)
Domain.Services (Implementation for domain services interfaces)
Infrastructure
Infrastructure.Data (Implementation for repositories and unit of work with EF)
Infrastructure.DependencyResolution (Implementation for IoC with Unity)
UI
UI.WebMVC
And here are my questions:
1- Am i right with these layers or i'm missing something ?
2- As for services that are related to a specific technology (e.g. Logging), where their interfaces should be (Domain.Interfaces or Infrastructure.Interfaces) ?
3- As i understand, The Domain Service will process my business use case so what are the benefits i'll get from application service
4- What are the differences between Domain Service and Application Service and in which project Application Service interfaces should be?
5- Should User Authorization process be a part of Application Services or Domain Services?
This a schema of hexagonal architecture, but it's really close to onion and IMO you should use that. Here are shown 3 layers: domain (yellow), application (red), infrastructure (green + blue). So answering your question - you are missing few pieces like application services.
Logging is probably not part of your domain logic, so it should be in infrastructure, both interface and implementation. To use it, you have to inject it to your application layer.
Domain services are taking care only of things that are related to your businness. Application services are most of the time preparing ground for domain services, in example creating repositories and retrieving aggregates from it, then calling domain services and passing that aggregates there. You shouldn't handle your business logic in app layer!
As I wrote in point 3. Application services should be in every projects that are using domain services.
Depends. User request your infrastructure layer with user credentials, infrastructure layer calls application layer with that credentials, there you try to retrieve user with given credentials, but first you convert raw password to hashed one with some functions. If user is found, you can authenticate user in infrastructure layer. Domain service wasn't needed here, but it's an exception.
I thought domain services should only represent domain concepts, but it seems we should also use them to control the granularity of domain layer interfaces ( which also prevents domain knowledge leaking into application layer ) and to decouple clients from entities and value object:
Eric Evan's DDD book, pg. 108:
Although this pattern discussion has emphasized the expressiveness of
modeling a concept as a Service, the pattern is also valuable as a
means of controlling granularity in the interfaces of the domain
layer, as well as decoupling clients from the Entities and Value
Objects.
Medium-grained, stateless Services can be easier to reuse in large
systems because they encapsulate significant functionality behind a
simple interface. Fine-grained domain objects can contribute to
knowledge leaks from the domain into the application layer, where the
domain object's behavior is coordinated.
a) If we also introduce domain services that don't represent domain concepts, but instead only control the granularity, don't we introduce non-domain concept into domain? If so, doesn't that hurt domain model?
b) Should most of communication with upper layers be done through medium-grained domain objects? Thus, for every use-case where communication happens through fine-grained domain objects we should introduce medium-grained domain service(s)?
c) Eric Evan's DDD book, pg. 108:
Coding conventions can make it clear that these objects are just
delivery mechanisms for SERVICE interfaces and not meaningful domain
objects.
What coding conventions is he referring to?
UPDATE:
I think you're saying that the quote is describing Application Services and not Domain services?
I'm aware of Application Services and of their purpose, but I think author is describing Domain Services, since he warns that knowledge leaks into application layer can happen due to fine-grained domain objects:
... as well as decoupling clients from the Entities and Value Objects.
Medium-grained, stateless Services can be easier to reuse in large
systems because they encapsulate significant functionality behind a
simple interface. Fine-grained domain objects can contribute to
knowledge leaks from the domain into the application layer, where the
domain object's behavior is coordinated.
And if we want to prevent knowledge leaks from domain layer into application layer, then shouldn't ( by my logic at least ) a "barrier" ( ie. a medium-grained service ) be built within domain layer?
SECOND UPDATE:
a)
With regards to granularity, a domain service serves a similar role to
an application service.
What kind of domain service are you talking about? One created only for the purpose of controlling the granularity or...?
b)
IMO, it is a matter of preference whether the application service
exists in a separate application layer project or together with other
domain objects.
You're calling a service ( the purpose of which is only to control the granularity ) an Application service even if it exists within a Domain layer?
c)
The application service does a fine job of preventing knowledge leaks
and in some sense, that is its central job.
But since a "barrier" ( ie. a medium-grained service ) exists within an Application layer, doesn't this mean that domain knowledge does leak into an Application layer ( but no further thanks to Application services )?
d)
We could say that Application layer is a client of Domain layer and author does warn throughout the book that no domain knowledge must leaks into a client. Why is Application layer ( ie Application services ) an exception to this rule?
Thanks
a) If we also introduce domain services that don't represent domain
concepts, but instead only control the granularity, don't we introduce
non-domain concept into domain? If so, doesn't that hurt domain model?
While the services don't introduce any new behavior into the domain, they don't introduce non-domain concepts either. I view these services, application services specifically, as providing an encapsulating role for the domain - a facade. Each method on the service represents a domain use case and it delegates directly to domain objects. This makes it much easier for clients of the domain layer, since they don't need to worry about coordinating repositories and calling suitable behavioral methods on aggregates. Instead, they invoke a method on the application service.
b) Should most of communication with upper layers be done through
medium-grained domain objects? Thus, for every use-case where
communication happens through fine-grained domain objects we should
introduce medium-grained domain service(s)?
Outer layers should call application services, which in turn delegate to aggregates or domain services. Note, application services are different from domain services. An application service can fully encapsulate the domain such that no domain objects are exposed by its interface, instead relying on DTOs to pass messages between outer layers and the application service. In addition to protecting the domain, this provides an opportunity to utilize something other than a domain model to implement use cases, such as a transaction script.
What coding conventions is he referring to?
One convention can be the presence of Application in service name, such as CargoApplicationService. Another convention is to place application services, which BTW can also be implemented as command handlers, into an Application module within the project.
EDIT
Take a look the this project on GitHub which implements the domain discussed in the book in a modern C# style.
UPDATE
With regards to granularity, a domain service serves a similar role to an application service. IMO, it is a matter of preference whether the application service exists in a separate application layer project or together with other domain objects. Creating an additional barrier between an application service and domain objects can become a needless abstraction. The application service does a fine job of preventing knowledge leaks and in some sense, that is its central job.
UPDATE 2
a) I was talking about domain services in general, because they all tend to increase granularity beyond entities and VOs.
b) Yes, because it still captures a domain concepts, namely use cases which are less granular then the domain objects used to implement them. Sure the application service has concerns largely orthogonal to the domain, but there isn't always a reason to put them into different layers.
c) Yes, but you can't get around leaking domain knowledge all together. If you have a database table with a name Customers which corresponds to the Customer entity, you have domain knowledge leaked into database. The point isn't to prevent all leaks, but to instead create boundaries around areas of cohesion, such that when making changes, they can be isolated to a specific layer.
d) Application service creates a facade around domain objects, effectively establishing a barrier so that clients of the domain, other than app service, have a clean interface to work with. In this way, app service is an "exception", because it sits between domain objects and outer layers.
We have added a Web API services layer to our application to help share the code with various product teams at my client's company. I like this as a way of managing versioning and for code organization but I'm concerned about violating Martin Fowlers First Law of Distributed Object Design, namely don't distribute your objects. We can host all of the various products on the same box currently and I was wondering if having the client application access our web services through localhost would allow us to avoid the issues that Martin is calling out. If it was WCF I would configure the end point to use Named Pipes and I guess I'm trying to figure out how to do that in IIS.
If you are hosting all your projects under the same process, it would be possible to go in-memory but I am not sure how much this makes sense. Here is a good example:
Batching Handler for ASP.NET Web API
A related post for the above one
It demonstrates the usage of in-memory hosting the entire Web API pipeline. However, in your case, it seems that this won't work out but might be worth considering.
I have a front end MVC application in a web role, protected by WIF and ACS, which I would like to be my Azure application's only exposed surface. It connects to a number of back end services, some worker roles and some (for the convenience of adding service references in VS, or because they use WCF Data Services) web roles. The back end service roles have only internal endpoints.
My understanding from the MS literature is that internal endpoints are available only to other roles with the same deployment. Given this, it seems redundant to apply any kind of transport or message security, or authentication, between the MVC web role and the back end services, which is presumably why https is not available on internal endpoints.
My question is: how secure is this? Is there any way an endpoint could be discovered from anything other than one of our deployed roles? Is there any reason to incur the overhead of additional security on any of the inter-role bindings?
A service represents an isolation boundary, unless you declare an endpoint as an "input" endpoint, it cannot be accessed outside of this isolation boundary. The implemetation of this boundary is a private network branch with no addressability to other branches.
Keep in mind that internal endpoints are not load balanced. So there is a trade off. I wrote some stuff up on endpoints awhile back that might help consolidate things a bit.
Can a domain entity can call or app service layer, through service layer interface ? Please tell me way also ?
In short, no.
Domain entities should not know about the application service layer. The application service layer's job is to coordinate actions between domain objects, across bounded contexts if necessary.
In my experience, this is a pretty strict rule so if you feel you need to break it you've probably got a design problem further up the chain.