Hi Everyone,
In this topic I want to cover another architecture pattern we have in Acumatica – Usage of context related parameters.
Problem Statement
Within the event model it is not easy to pass parameters into the other child or related events. There is a way with local variables how it is shown in T300 Training Guide and Override Release Action Lesson.
However it is a really not nice approach if events happens in different objects like here:
public class SomeGraph : PXGraph<SomeGraph> { public void CreateBatch() { bool needValidate = true; //Create Batch } } public class JournalEntry : PXGraph<JournalEntry> { public void DAC_RowUpdated(PXCache cache, PXRowUpdatedEventArgs) { if (needValidate) { ... } } }
Solution
In Acumatica we use an approach that we call Scopes. Scope is a class that set any environment related variable in the constructor and than reset variable back during destruction. To make sure that object is properly disposed this approach uses IDisposible interface and using(…) C# construction.
Here you can see the example of scope class:
public class MyScope : IDisposable { protected bool _Flag; protected readonly MyScope _Previous; public MyScope(bool flag) { _Flag = flag; _Previous = PXContext.GetSlot<MyScope>(); PXContext.SetSlot<MyScope>(this); } public void Dispose() { PXContext.SetSlot<MyScope>(_Previous); } public static bool GetFlag() { MyScope scope = PXContext.GetSlot<MyScope>(); return scope == null ? false : scope._Flag; } }
And here you can see usage of scopes:
using(MyScope scope = new MyScope(false) //... // Calling of other events, methods, objects. //... }
In the nested events/methods you can use scope to extract context variable:
using(MyScope scope = new MyScope(false) { //... if(MyScope.GetFlag()) { /* ... */ } //... }
In these examples you can see that I’m using “PXContext.SetSlot<T>()”. In Acumatica we have 2 types of slots:
- PXContext.SetSlot<T>() – are Thread related variables that stores a variable only in the current thread. As soon as round-trip is finished the variable will be destroyed.
- PXDatabase.SetSlot<T>() – are Database variables that won’t be destroyed after the round trip and you still can use them later. Read more about Acumatica database slots here.
There are many other scopes usage within Acumatica that you can see within a code.
Have a nice development!