DDD Call Adapter from Within Domain Object - domain-driven-design

I am implementing a Hexagonal Architecture with Domain Driven Design.
I have a Value object called "Address" that has a "validate()" method.
I would like to have a default validation provider for the address that is within my domain, but also allow external users to provide an overridden validator.
So I created an AddressValidationAdapter interface that can be implemented by the outside world in "dependency inversion" manner.
My question is - what is the best way to call my AddressValidationAdapter from within my Address class ?
Do I need to add it as a dependency in its constructor ?
Should I use some sort of global / static context ?
Should I use event driven approach where I post a "ValidationEvent" within my domain and subscribe to a validation success notif ?
Should I create a Service that orchestrates everything ? (Seems not very DDD like)
Thank you very much for your thoughts.
Best Regards
Alex

You mention Domain Driven Design, which is a practice that requires all business related code to go in a domain layer, and all non-busines related code to go out of that domain layer. Other than that, DDD is more concerned by how you design and evolve your business model, not so much about application architecture. The author of the DDD concept states that it can be used with any software architecture.
You also mention Hexagonal Architecture, which addresses software architecture, and has more constraints on how you structure your code. Hexagonal Architecture defines 3 concentric layers in applications:
The domain layer validates that state changing values do not violate business rules;
The ports layer is a business representation of infrastructure interactions;
The adapters layer implements the actual communication with external infrastructure.
Hexagonal Architecture also states that type references should go inwards, which means ports are not allowed to reference adapters, and the domain model is not allowed to reference other layers. A good practice is also to forbid direct reference accross different adapters. However, this is not much of a concern in your situation.
Address validation is definitely not an adapter layer concern, because it is not related to how your application interacts with an external infrastructure or data structure. This means that address validation should not be implemented as an adapter, in the sense of Hexagonal Architecture. It is not a port either for the same reasons. Address validation should go in the domain layer, because business rules validation is the purpose of the domain layer (Hexagonal Architecture) and all business related code should go in the domain layer (DDD).
However, neither DDD nor Hexagonal Architecture state anything on how you should structure your domain layer internally, so it is up to you. If you want your application to use different validation implementations, you may want to use the adapter pattern in cunjunction with a dependency injection library. Note that "adapter", here, refers to a software engineering desing pattern that has inspired the Hexagonal Architecture concept of adapter layer, but is totally independant from it.
Since the purpose of the domain layer is to validate state changing data, there should be very little code apart from validation rules implementation and data structure. If you move the latter to a validator class, there will be little left to write in the domain model objects themselves. You are probably going to end with an anemic domain model this way. You might want to consider implementing Always Valid State domain model, where validation rules are implemented directly in the domain model's setters and constructors.
If you wrote an adapter class due to the fact that you need to retrieve external data to do the actual validation, this is a good evidence that your domain model is lacking information and should be extended, rather than violating Hexagonal Architecture constraints.

Do I need to add it as a dependency in its constructor ?
Absolutely no! Value object are data and you are putting yourself in a hell with serialization/deserialization for it
Should I use some sort of global / static context ?
Not sure what you mean, but global/static context is scary, what about multiple validation done in parallel?
Should I use event driven approach where I post a "ValidationEvent" within my domain and subscribe to a validation success notif ?
Domain events are related to entities state changes, nothing is changing when you do validation
Should I create a Service that orchestrates everything ? (Seems not very DDD like)
It could be...
but also allow external users to provide an overridden validator.
I'm very curious of the details of this, why an external user would need a different validation?
Could it be that an Address has some sort of generic validation that need to be always checked, but different use cases have more stricter rules?
If that's the case why the Address itself would need to know them? It is just a value! An Integer just know that it has to be a number if in certain usage you need it to be in a range of values it's something that you add to it, but it doesn't know about it
DI/IoC approach is good and I was thinking you could do something like:
class Address {
....
validate(AddressValidationAdapter customValidation) {
// generic validation then...
customValidation.validate(whatAreYouPassingHere)
}
}
Whatever you are using as whatAreYouPassingHere, can't the code doing:
Address address = ...
address.validate(customValidator)
just read the values needed from the address and do its own validation?

Related

Specifications Pattern crossing bounded context - Domain Driven Design

I'm trying to understand and implement with good practice the Specification Pattern within my domain driven design project.
I have few questions:
For example: verifying that a customer is subscribed before update a data on a aggregate is it part of business rule and should sit in the domain layer?
Can specifications cross bounded context? For exemple, i have a Subscription bounded context where we can find a specification called SubscriptionIsActive. In a second bounded context let's call it PropertyManagement. I would like to call SubscriptionIsActive specification as an User need to be a subscriber to create a Property aggregate. My specification here is crossing bounded context and i don't think it's right choice, any recommandation, tips?
Where should instanciate the specification when we want to use it, Application layer (that contains, commands and query, we use cqrs) or Domain Layer wihtin the aggregate root?
At the end, where should access control like (User has rights to edit some aggregate) sit in a domain driven design, Domain Layer or Application Layer in services before calling the aggregate?
Thanks
My recommendation is that a domain should not call out to obtain additional information/data. This means that everything a domain needs should be handed to it and the domain performs the transactional processing.
All authentication/authorization takes place outside the domain and access to the relevant domain operations is granted based on the identity/access outcome.
I have found specifications most useful on the data querying side of things. Usually there are multiple permutations w.r.t. how data is retrieved and a specification encapsulates the various possibilities quite nicely (GetByName,GetByNameAndType,etc.) This doesn't mean that you cannot use a specification in the domain. You may have some complex piece of functionality to determine qualification of a domain object and in that case a specification operating on the relevant domain object would be a good fit. To that end a specification doesn't cross a domain as it would be part of a particular domain. In much the same way as a specification is useful in a data querying scenario you may have a specification in the integration/application concern and have it determine qualification based on data from multiple domains such as in your second example. This may even be something that is applied in a process manager implementation (integration).
Not all business rules need to be specifications and if, as in your first case, a customer is not subscribed then your integration/application processing would stop any further transactional changes much as it would for an authorization failure.

DDD - Domain Service Implementation: Domain or Infrastructure

I have this classic DDD problem; I have a Domain Service "DetectPriority" that do some stuff.
PM ask me to create 2 different services; one INTERNAL ( with is FULL of business rules and involve many other Domain Models ) and another one ETERNAL ( a simple API call ).
There is a interface "DetectPriorityInterface" within the Domain.
Both Implementations MUST be active in the same time; a kind of "mixed" has to select one instead of the other in real time.
The problem is: Where do these implementations ( two implementations ) should live: in Domain Layer or Infrastructure Layer??
Internal Implementation is full of business rules and should reside in Domain Layer.
External Implementation is a simple CALL and should lives in Infrastructure.
Should we put both in Infrastructure layer?
Thanks
EDIT
Actually we have one interface "DetectPriority" and three implementations, ALL in our Domain layer ( temporary "wrong" solution ) :
InternalDetector ( with Business Rules )
ExternalDetector ( With external API call )
MixerDetector ( get both Implementations and handle the choise )
Clients use the Interface so, for Application Layer, all these stuff are trasparent; in the next, we will remove the Internal ( or External ) and Mixer and use only One Implementation. ( The idea behind all these is to understand who performs better, it is an A/BN test )
Our internal debate is: Cause InternalDetector has some domain rules that belongs ONLY to that Detector, it should live in Infrastructure layer, cause it is not an General Domain Rules. Some of us disagree with this, cause in InternalDetector we only have business rules and we don't see that in Infra Layer.
Problably the correct way should be add Internal in Domain, and External in Infra .. but it seems to be a bit confused ..
Putting all together in Infra layer would be more readable for devs...
We didn't find some stuff in books cause usually you have a single implementation of a domain service ....
The short answer is that you should implement an internal service in the domain layer and an external one in the infrastructure layer, exactly as you said in your question. This way, everything will be in its place.
An additional important thing to consider is that the code that decides which service to call should be in the domain layer too. As I can imagine from your question, you decide which detector to use using some business rule. That fact that one detector is implemented in your application, and another one is not is just an implementation detail of your system. In fact, you just decide to use one set of business rules or another one according to some condition. It is a business decision.
DDD is pretty often about difficult compromises. But when you are looking for a good compromise, I would advise never move the domain logic outside of the domain layer, and never add references from the domain layer to other ones.
This is essential.
And here is an example of how you can solve this task without violation of these rules:
// Names in this code should be changed to something with business
// meaning. For example `externalDetector` can be `governmentDetector`
// and `internalDetector` can be `corporateDetector`.
// Declare a service interface in the domain layer
public interface DetectPriority {}
// Inject both detectors in the domain service.
// Your dependency injection code should inject here
// an internal implementation and an external one,
// implemented in the infrastructure layer.
// So your DI code knows about different implementations
// but the domain service doesn't.
// For the domain service it's just two implementations
// of domain interface IDetector
IDetector _externalDetector;
IDetector _internalDetector;
// Implement the method of the domain service like this:
public Priority Detect()
{
if (weShouldUseExternalSetOfRules)
{
return _externalDetector.Detect(); // this one is implemented in your infrastructure layer
}
else
{
return _internalDetector.Detect(); // this one is implemented in your domain
}
}
In this solution you can see that:
All domain logic (an implementation of internal detector and decision which set of rules to use) is placed in the domain layer.
We don't have references to the infrastructure layer from our domain. The domain service have the reference only to IDetector interface, but this interface is declared in the domain layer.
There is not infrastructure code in the domain layer. In this case, infrastructure code means something like "call that GET method of that REST service using this set of parameters in the query string". Obviously, this code will be in the externalDetector implementation.
To be sure that it is a good way, you can take a look at this repository with a sample DDD application from famous Eric Evans' book. You can find there a service interface declared in the domain layer and the service itself implemented in the infrastructure layer. Unfortunately, there aren't examples of using this service interface inside of the domain layer in this application. But it's declared inside of the domain layer to make such a usage possible.
And you can find the same approach with a good explanation in this great article.
EDIT
According to new information in the question, if it is about A/B testing, then choosing a detector is the application-level decision. All other things remain the same. So:
MixerDetector should be in the application layer
DetectPriority interface - in the domain layer
InternalDetector in the domain layer
ExternalDetector in the infrastructure layer
And you don't need "business" names for your detectors then, because they are literally InternalDetector and ExternalDetector.
Should we put both in Infrastructure layer?
Not usually, no. Among other things, that's going to make a mess of your dependency graphs. We don't want domain code to have a dependency on infrastructure code (one of the motivations for having a domain model is so that you can implement the logic of the domain without being tightly coupled to the context that runs the domain model -- introducing infrastructure dependencies is contrary to that goal).
That doesn't necessarily mean that the infrastructure code is "far away" - see package by feature vs package by layer. They are different responsibilities (in the single responsibility principle sense), so there will usually be some separation between the two.
One aspect in which the two are very different: failure modes -- robust code that communicates across the network needs to respect the fact that the network is unreliable, but that's not a domain concern, so we don't usually want to pollute our domain code with network contingency logic.
But if you like, ignore all that -- the real heuristic is simple: we want the arrangement of code that is easiest to maintain over its entire lifetime. If in your context that means putting domain code into the infrastructure layer, then that's what you should do.
The guidelines of DDD and other styles are primarily there to help you avoid the trap of increasing the lifetime maintenance cost by deciding to do what is easy "right now".
I use to keep domain service implementations which are free of infrastructure dependencies in the domain layer. Implementations of a domain service interface which require infrastructure dependencies should reside in the infrastructure layer.
What you need to consider as well in your case is that the code which instantiates the concrete implementation of your DetectPriorityInterface at runtime has to reside in the infrastructure layer as well as it also has a direct dependency to the external domain service.
I suggest you have some factory for that job which decides on creating one or the other domain service based on some kind of parameter. But you can still use a factory interface which you can put in your domain layer. Let's call it PriorityDetectorFactoryInterface or similar. And only the concrete implementation of that factory, let's call it PriorityDetectorFactory would reside in the infrastructure layer.
If you have some application service which is responsible for handling the use case where the priority detection comes into play you would pass the PriorityDetectorFactoryInterface into this application service. At runtime the concrete implementation of the factory interface (i.e. PriorityDetectorFactory) will be injected into the application service. With that you can also keep the application layer where you usually only define the workflows for orchestrating your use cases free of infrastructure dependencies.
With that you would have:
DetectPriorityInterface in your domain layer
InternalPriorityDetector (implementing DetectPriorityInterface) in your domain layer
ExternalPriorityDetector (implementing DetectPriorityInterface) in your infrastructure layer
PriorityDetectorFactoryInterface in your domain layer as well
PriorityDetectorFactory (implementing PriorityDetectorFactoryInterface) in your infrastructure layer
...and the mentioned application service handling your use case in your application layer
Note: this is all based on the assumption that your internal domain service implementation is really free of dependencies other than stuff from the domain layer itself.

DDD - which layer DTO should be implemented

I am learning about DDD so apologies if my question is naive. I think I need to use Local Data Transfer Object in order to display data to the users as a lot of properties are not part of any of Entity / Value Objects.
However, I am not sure where this DTO should be implemented - in a Domain Layer or in an Application Service Layer. The DTO implementation seems part of the Domain, but it means that when I create a collection of DTOs in the Service Layer and pass it to a Presentation Layer, I have to reference Domain Layer in Presentation Layer, which seems wrong.
What is the correct way to implement DTO using DDD principles?
Define the DTO to the layer where the source of the values comes from.
Relative to OP's question: place the DTO in the Application Service Layer. DTO is an output of that layer, it makes sense if you define it there. Don't put your DTO in the Domain Layer. The Domain Layer does not care about mapping things to serve external layers (the domain does not know there is a world outside of its own).
Presentation Layer (closes to consumers)
This could be your API
Has Models or Dto definitions of its own with attributes relative to its layer. If this is an API then Models/DTO have attributes for formatting or data type validations
This is the "Application Root" (meaning that it must reference both Domain Service layer, Data/Infrastructure Layer to be able to inject services)
Maps data between ApplicationService.Dto and Presentation.Dto
Application Service Layer
Has Dto definitions of its own to be able to return data without exposing the domain entities.
Bridge between Presentation Layer and Domain Layer.
Contains Application Services. See answer https://stackoverflow.com/a/3840552/1027250 for detailed definition of Application Services.
Domain Layer
Domain entities
May contain Interfaces bridging the infrastructure layer, defined in words that can be understood by the business, free from technical terms (IE: IExcelReport, IGoogleSheetReport, IRepository)
May contain "Domain Services"
Data / Infrastructure Layer (closest to your database or external services)
Database infrastructure (mapping).
Excel libraries if you define this layer as infrastructure code.
Mail or notification services.
PDF output files
Such DTOs that are exposed to the outside world become part of a contract. Depending on their form, a good place for them is either the Application Layer or the Presentation Layer.
If the DTOs are only for presentation purposes, then the Presentation Layer is a good choice.
If they are part of an API, be it for input or output, that is an Application Layer concern. The Application Layer is what connects your domain model to the outside world.
As an interesting observation, it follows that the Presentation Layer should access the domain model only through the Application Layer. Otherwise, we lose our single point of access - we'd have multiple layers invoking the domain model. The Application Layer exposes all of our use cases. Whether they are invoked by a call from another service or by the Presentation Layer makes little difference.
Sources
The core of these concepts I learned from The Red Book by Vaughn Vernon. (I would quote from it, but I don't have it handy.) The chapters about the Application Layer and the Presentation Layer are relevant.
Primarily, my conclusions come from being strict with the concepts as presented by Eric Evans and Vaughn Vernon, and prioritizing freedom in the domain model, as this is Domain-Driven Design:
The domain model should be easy to change. That means not exposing domain objects externally, as having external dependants would make them hard to change (without breaking things).
The Application Layer is the external point of access. It is what defines the use cases on the domain model. That means not operating on the domain model from elsewhere. The Presentation Layer can only go through the Application Layer. Nobody likes having to deal with many different points of access!
Yorro is right about where to place DTO but I encourage you to avoid "DTO mindset". This way of thinking collides with DDD way of thinking.
Thinking about "I need a DTO here" is thinking about technical representation (as plalx says); it is a level of abstraction too low. Try a higer level of abtraction and think about your domain, user's tasks and your UI.
Do you need get view data to the user? Bring it to UI through a View Service that return a specific YourViewInfo class.
Do you need to send data to some Service to perform a task? Send it a specific TaskMessageInfo class or a specific Command class.
When you begin to modeling the internals of these classes is when you should start to thinking about its technical representation; then you could reach to the conclusion that could be, i.e., DTO classes for convenience.
Thinking this way helps you to model the system and doesn't trigger questions like
Where to put or belongs this thing?
DTO and Domain are different layers.
So it requires mapping from one to another and usually it is done in what is called Application Services layer.
Take a look at the following articles to go deeper with DTO and layering:
Is Layering Worth the Mapping? by Mark Seemann
DTO vs Value Object vs POCO: definitions
Hexagonal (Ports/Adapters) Architecture
What has to be mentioned here is so-called Hexagonal (Ports/Adapters) Architecture [Vernon, the red book p. 125]. It is very convenient to place objects that represent data for the external (outside the domain & the application) comsumers. The architecture is the great addition to Layered Architecture generally implied by DDD.
Here is the example.
Along with ports/adapters for a DBs, email services etc.
We may define a ports/adapters/http/ui/myestore/ShoppingCartResponse.valueobject.ext (assume we use some imaginary programming language EXT) that contains the data your UI application MyEStore will use to show the end user his shopping cart state.
ShoppingCartResponse.valueobject.ext is created by ports/adapters/http/ui/myestore/EStoreHTTP.adapter.ext (for brevity it could be a synonim for a very slim HTTP REST API controller from REST world in our example).
The adapter asks the domain service ShoppingCart.service.ext for aggregates, entities, other value objects. Then it creates the desired ShoppingCartResponse.valueobject.ext from them (by itself or with creators - factories, builders etc.). Then sends the value object as an HTTP response to the consumer.
DTO or Value Object?
Whether ShoppingCartResponse would be a value object or a DTO (.dto.ext) you should decide based on
The particular structure of your Ports/Adapters object hierarchy;
If it is justified to have another type of object, a DTO, in the system, or it is better to keep only value objects only;
A semantic meaning of DTO vs value objects in object hierarchy;
The responsibilities differentiation between them: say your value object would do some invariants logic-keeping, whereas DTO could be just a dumb object with no logic.
I would prefer starting with the simplest approach, allowing only for value objects, and add DTOs only as the clear architectural need in them appears.
This approach gives much flexibilty yet it keeps code design clean and simple. Ports/Adapters section accommodates objects that belong together (the adapter, VO or DTO, their creators) and keeps Application Layer clean keeping the space for more relevant application layer objects.

Having trouble putting real-world logic into the DDD domain layer

Despite having studied Domain Driven Design for a long time now there are still some basics that I simply figure out.
It seems that every time I try to design a rich domain layer, I still need a lot of Domain Services or a thick Application Layer, and I end up with a bunch of near-anemic domain entities with no real logic in them, apart from "GetTotalAmount" and the like. The key issue is that entities aren't aware of external stuff, and it's bad practice to inject anything into entities.
Let me give some examples:
1. A user signs up for a service. The user is persisted in the database, a file is generated and saved (needed for the user account), and a confirmation email is sent.
The example with the confirmation email has been discussed heavily in other threads, but with no real conclusion. Some suggest putting the logic in an application service that gets an EmailService and FileService injected from the infrastructure layer. But then I would have business logic outside of the domain, right? Others suggest creating a domain service that gets the infrastructure services injected - but in that case I would need to have the interfaces of the infrastructure services inside the domain layer (IEmailService and IFileService) which doesn't look too good either (because the domain layer cannot reference the infrastructure layer). And others suggest implementing Udi Dahan's Domain Events and then having the EmailService and FileService subscribe to those events. But that seems like a very loose implementation - and what happens if the services fail? Please let me know what you think is the right solution here.
2. A song is purchased from a digital music store. The shopping cart is emptied. The purchase is persisted. The payment service is called. An email confirmation is sent.
Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction? Of course I could put everything in the MVC controller with injected services. But if I want real DDD all business logic should be in the domain. But which entity should have the "Purchase" method? Song.Purchase()? Order.Purchase()? OrderProcessor.Purchase() (domain service)? ShoppingCartService.Purchase() (application service?)
This is a case where I think it's very hard to use real business logic inside the domain entities. If it's not good practice to inject anything into the entities, how can they ever do other stuff than checking its own (and its aggregate's) state?
I hope these examples are clear enough to show the issues I'm dealing with.
Dimitry's answer points out some good things to look for. Often/easily you find yourself in your scenario, with a data shoveling from db up to GUI through different layers.
I have been inspired by Jimmy Nilsson's simple advice "Value objects, Value objects and more Value objects". Often people tend to focus to much on Nouns and model them as entity. Naturally you often having trouble in finding DDD behavior. Verbs are easier to associate with behavior. A good thing is to make these Verbs appear in your domain as Value objects.
Some guidance I use for my self when trying to develop the domain (must say that it takes time to construct a rich domain, often several refactoring iterations...) :
Minimize properties (get/set)
Use value objects as much as you can
Expose as little you can. Make you domain aggregates methods intuitive.
Don't forget that your Domain can be rich by doing Validation. It's only your domain that knows how to conduct a purchase, and what's required.
Your domain should also be responsible for validation when your entities make a transition from one state two another state (work flow validations).
I'll give you some examples:
Here is a article I wrote on my blog regarding your issue about anemic Domain http://magnusbackeus.wordpress.com/2011/05/31/preventing-anemic-domain-model-where-is-my-model-behaviour/
I can also really recommend Jimmy Bogard's blog article about entity validations and using Validator pattern together with extension methods. It gives you the freedom to validate infrastructural things without making your domain dirty:
http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/
I use Udi's Domain Events with great success. You can also make them asynchronous if you believe your service can fail. You also wrap it in a transaction (using NServiceBus framework).
In your first example (just brainstorming now to get our minds thinking more of value objects).
Your MusicService.AddSubscriber(User newUser) application service get a call from a presenter/controller/WCF with a new User.
The service already got IUserRepository and IMusicServiceRepository injected into ctor.
The music service "Spotify" is loaded through IMusicServiceRepository
entity musicService.SignUp(MusicServiceSubscriber newSubsriber) method takes a Value object MusicServiceSubscriber.
This Value object must take User and other mandatory objects in ctor
(value objects are immutable). Here you can also place logic/behavior like handle subscriptionId's etc.
What SignUp method also does, it fires a Domain Event NewSubscriberAddedToMusicService.
It get caught by EventHandler HandleNewSubscriberAddedToMusicServiceEvent which got IFileService and IEmailService injected into it's ctor. This handler's implementation is located in Application Service layer BUT the event is controlled by Domain and MusicService.SignUp. This means the Domain is in control. Eventhandler creates file and sends email.
You can persist the user through eventhandler OR make the MusicService.AddSubscriber(...) method to this. Both will do this through IUserRepository but It's a matter of taste and perhaps how it will reflect the actual domain.
Finally... I hope you grasp something of the above... anyhow. Most important is to start adding "Verbs" methods to entitys and making the collaborate. You can also have object in your domain that are not persisted, they are only there for mediate between several domain entities and can host algorithms etc.
A user signs up for a service. The user is persisted in the
database, a file is generated and saved (needed for the user account),
and a confirmation email is sent.
You can apply Dependency Inversion Principle here. Define a domain interface like this:
void ICanSendConfirmationEmail(EmailAddress address, ...)
or
void ICanNotifyUserOfSuccessfulRegistration(EmailAddress address, ...)
Interface can be used by other domain classes. Implement this interface in infrastructure layer, using real SMTP classes. Inject this implementation on application startup. This way you stated business intent in domain code and your domain logic does not have direct reference to SMTP infrastructure. The key here is the name of the interface, it should be based on Ubiquitous Language.
A song is purchased from a digital music store. The shopping cart
is emptied. The purchase is persisted. The payment service is called.
An email confirmation is sent. Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction?
Use OOP best practices to assign responsibilities (GRASP and SOLID). Unit testing and refactoring will give you a design feedback. Orchestration itself can be part of thin Application Layer. From DDD Layered Architecture:
Application Layer: Defines the jobs the software is supposed to do and directs the
expressive domain objects to work out problems. The tasks this layer
is responsible for are meaningful to the business or necessary for
interaction with the application layers of other systems.
This layer is kept thin. It does not contain business rules or
knowledge, but only coordinates tasks and delegates work to
collaborations of domain objects in the next layer down. It does not
have state reflecting the business situation, but it can have state
that reflects the progress of a task for the user or the program.
Big part of you requests are related to object oriented design and responsibility assignment, you can think of GRASP Patterns and This, you can benefit from object oriented design books, recommend the following
Applying UML and Patterns

Service Layer validation vs. Domain Object validation; potential "abuse" of Domain Objects?

I've seen lots of book and article examples saying to put validation code in your Service Layer. Keep the Domain Objects "dumb" (aka, pure POCO's) and handle all validation that a Domain Object might do in the Service Layer.
The Service Layer is responsible for so much it seems (or at least it can be); user authentication, role authentication, scripting dependency objects for IoC's (loggers, error-handlers, etc...), scripting Domain Objects, scripting repositories and passing Domain Objects to and from the repository... whew!
Doesn't creating all these rules in the Service Layer pose a substantial threat to your Domain Objects? For instance, what happens is some programmer decides to write consuming code directly against your Domain Objects and just bypasses the Service Layer altogether? That would be bad, but a believable situation.
If you are going to put a lot of the responsibilities in the Service Layer, including all Domain Object validation, is there a way to "protect" your Domain Objects is someone tries to script them directly? For instance, maybe some way your Domain Objects now they're not being used by a certain client (in this case, the Service Layer?).
Good design makes me think the Domain Objects should know nothing about who's calling them and how they're being called.
If there is no way to "lock down" the Domain Objects, then why are so many articles, books, etc suggesting that putting Domain Object validation in the Service Layer the way to go? I would imagine by taking a defensive programming position, that you should build your Domain Objects to be bullet-proof, and rely on your Service Layer for a simple layer of code to forwarding and receiving requests between the UI and the BAL/DAL.
Has anyone had some real-life project experiences with "abuse" of their Domain Objects from people that have bypassed their Service Layer?
I think you may misunderstand the purpose of a POCO. A POCO, as I understand it, is not an anemic domain object with only properties and attributes. Rather a POCO simply is not tied to a framework or complicated inheritance model. The object is flexible and only concerned about its role in the domain.
They are 2 different design philosophies. Rich Domain Model vs Anemic Domain Model.
The short answer is yes, you can prevent direct access to your domain objects.
You can do so with a number of techniques:
1) You can make all public facing domain objects immutable (i.e. you can't change the data) via only having the only public methods be getters. All methods that modify your objects can be protected or package private so only the correctly packaged services can access them (in Java at least)
2) You can expose only separate classes to your external developers -- so if you have a Person domain class you can have a PersonInfo class that you pass up, that does nothing but contain info.
3) You should expose a coherent API to your app consumers. You basically prevent them from bypassing your Service layer.

Resources