[
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)