[ 
https://issues.apache.org/jira/browse/ISIS-1807?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16316256#comment-16316256
 ] 

Oscar Bou commented on ISIS-1807:
---------------------------------

Hi, Dan.

Yes, all our codebase is plenty of "wrapped" calls. It's mandatory according to 
our internal standards to always invoke inside a "wrap" call any setter and 
action.

Fully agree is that my intent is to guarantee those trust boundaries, but 
assuming they're directly related to a given Domain Entity and associated 
sub-entities (i.e, Aggregated Root in DDD terms).
So every invocation from one Service or Domain Entity to actions on another 
Domain Entity or Services (or setters from a Domain Entity) are always wrapped 
to ensure invariants protection through the domain logic embedded:
* on the action implementation
* the "modifyXXX" method from the default programming model
* or the domain event handlers basically.

Regading, View Models, it's a related case that it's worth considering. 
Wrapping invocations could be a way to ensure its immutability. For example, 
invoking a setter would throw by default an Exception if not invoked inside a 
"WrapperFactory.wrapSkipRules(...)" call. 

> Wrap Domain Entities by default
> -------------------------------
>
>                 Key: ISIS-1807
>                 URL: https://issues.apache.org/jira/browse/ISIS-1807
>             Project: Isis
>          Issue Type: Improvement
>          Components: Core
>    Affects Versions: 1.15.1
>            Reporter: Oscar Bou
>             Fix For: 2.0.0
>
>
> This way, all hide/disable/validate constraints, and other 
> constraints/invariants forced through actions, are always ensured by default.
> This will require to wrap by default:
> * New Domain Entity instances / objects (ie, changes on FactoryService).
> * Domain Entities returned by queries (ie, changes on RepositoryService).
> Users might disable this new default behaviour through configuration, as some 
> projects can prioritize performance (avoiding wrapping invocations) vs Domain 
> constraints/invariants enforcement.
> ~~~~
> Dan's notes:
> I'd like to refine the concept of wrapping while implementing this ticket.
> The idea of wrapping was originally to allow the UI to be simulated within 
> integration tests.  The intent of this ticket is to formalize the idea of the 
> same set of validations being done automatically between programmatic 
> interactions from one service/entity to another service/entity.  
> So, the more general concept (common to both UI/domain interactions and 
> domain-to-domain programmatic interactions) is one of _trust boundaries_.  If 
> there is no trust from the calling client to the supplying service/entity, 
> then that interaction should be wrapped.
> However, the wrapping model as it currently stands is a little bit too 
> UI/domain oriented, in that it has both hidden AND disabled as well as 
> validate phases.  From the perspective of a programmatic domain-to-domain 
> interaction there's no meaningful distinction between the hidden and disabled 
> constraints: they both mean: "that object isn't in a state to be called".  In 
> other words its a pre constraint that is not satisfied.
> The other aspect here is that I can imagine that there are actions that we 
> would like to allow to be made programmatically (ie through a wrapper) but 
> which shouldn't be part of the UI.  In other words these actions form part of 
> the programmatic API of a module, just not part of its UI.
> Putting all this together, I propose that we slightly change the meaning of 
> wrapping (though we'll keep the current implementation too for backwards 
> compatibility), namely that by default wrapped object will check the disable 
> and validate phases only, ie it will _not_ check the hidden phase.  This 
> allows such actions to be indicated as hidden (probably using @ActionLayout 
> or .layout.xml or security) but still able to be called programmatically.  
> The disable phase = pre check.
> We could define the following terminology:
> - "default" wrapping : as described above, checks only disable and validate, 
> not hidden
> - "strict" wrapping - for backward compatibility, also checks hidden first
> We could define a configuration property:
> isis.runtime.wrapping=default | strict | none
> with "default" wrapping being the default if not specified.
> In terms of the programming API, the WrapperFactory#wrap(...) will obviously 
> be less important than it was, because by default objects will be wrapped.  
> For backward compatibilty, I think this should continue to create strict 
> wrappers
> The wrap(...) method is also overloaded, with wrap(ExecutionMode).  We can 
> extend this enum:
> - EXECUTE - (existing) returns a strict wrapper
> - SKIP_RULES - (existing) skips applying the hidden/disable/validate rules
> - NO_EXECUTE - (existing) applies hidden/disabled/validate, but does not 
> execute
> - DEFAULT - (new) returns a "default" wrapper, applies only disable/validate 
> but not hidden
> (new:) if the object passed in is already wrapped, then it should be replaced 
> with a wrapper with the specified mode.  Prevoiusly this was a no-op, I think.
> The unwrap(...) method is unchanged.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to