There is currently no way to add a behavior that wrap handler invocations but still execute withing the synchronized storage session. This can be solved by a new UnitOfWork stage.
This also provides a UoW API very similar to the current proposal for a new UoW api so this would kill 2 birds with one stone.
This is technically not a breaking change but a major seems like the right time to do it.
See this spike for inspiration if/when implementing this
a good point raised by @jasondentler is the fact that we should make sure that we resolve the handlers after the UoW stage so that custom DI registration can be used by message handlers.
@timbussmann tricked me into tackling this. After diving into this I stopped working on it because I think there are a few things that need to be discussed first before we continue on this. The current work can be found https://github.com/Particular/NServiceBus/tree/uow-stage
Unfortunately it is not as simple as just introducing an UoW stage. The terminology Unit of Work is already used and defined by https://docs.particular.net/samples/unit-of-work/ and https://docs.particular.net/samples/pipeline/unit-of-work/. If you look at that doco UoW relates to physical stage thus allowing to intercept any exceptions that would happen when the synchronized storage session without outbox throws.
Furthermore, the doco mentions this
In Version 6 IManageUnitsOfWork does not wrap the persistence transaction. The persistence transaction can therefore still fail after the unit of work completed.
https://docs.particular.net/nservicebus/pipeline/unit-of-work#implementing-custom-unit-of-work
When you have an outbox transaction that sentence is correct. When you don't have an outbox transaction the sentence not entirely correct.
Anyhow my point is that the term UoW is defined by IManageUnitOfWork or hooking into the physical part. If we want to continue with this I see the following option:
IManageUnitOfWorkand the UnitOfWorkBehaviorIIncomingUnitOfWorkContext(since with the message session UoW we might have an outgoing session as well once?)The downsides of this is that yet again we remove a high level abstraction and push users towards using the pipeline more. Not sure it is necessarily a bad thing but it has to be considered
I'm starting to think that we should name the stage differently instead.
Looking at what the code does could we call it StorageStage or DeduplicationStage etc?
You would then insert your own "BlaBlaBlaUnitOfWork" into that stage?
Bumping this to Future after talking to @timbussmann , there is no pressure currently to get this in and we can potentially do this in a minor should the need arise
Agree.
I think from an internal perspective there is more value in having a dedicated dispatch pipeline as outlined in https://github.com/Particular/NServiceBus/pull/4847 since that would allow us to stream line stamping behaviors over all transports for ATTs
@andreasohlund I propose to close this as this seems to be something for the pdev process to handle?
What would be the problem that this solves? "Users can't extend behaviors in the storage session part of the pipeline" ?
yeah something like that I'd say :D
Closing this as we're unlikely to act on this in the near future. We're keeping an eye on this internally for now
Most helpful comment
a good point raised by @jasondentler is the fact that we should make sure that we resolve the handlers after the UoW stage so that custom DI registration can be used by message handlers.