-
-
Notifications
You must be signed in to change notification settings - Fork 42
SequenceGenerator
The SequenceGenerator
updates Business Objects members with unique sequential values.
Credits: to Brokero that sponsor the initial implementation of this module.
This platform agnostic
module is a well tested implementation variation of the E2829. The module can be configure to generate unique numerical sequences per ObjectType/memberName combination.
In details: when any XAF database transaction starts an Explicit UnitOfWork is used to acquire a lock to the SequenceStorage
table. If the table is already locked the it retries until success, if not it queries the table for all the object types that match the objects inside the transaction and assigns their binding members (e.g. a long SequenceNumber member). After the XAF transaction completes with success or with a failure the database lock is released. A long sequential number is generated only one time for new objects.
Our Invoices and Orders must use unique sequential values in a multi user environment. How can we do it? without sparing my resources?
Traditionally:
This is a non-trivial to implement case without space for mistakes. Therefore a substantial amount of resources is required to research and analyze taking help from existing public work. Do not forget that the requirement is to be super easy to install and use in any project and to be really trustable, so unit and EasyTest is the only way to go in a CI/CD pipeline.
Solution:
The cross platform Xpand.XAF.Modules.SequenceGenerator generates unique sequential values and provides a XAF UI so the end user can link those values to Business objects members. Its unit and EasyTest run for the latest 3 Major XAF versions with the help of Xpand.VersionConverter
In the next screencast we use the XAF UI to create a subscription
to the sequence
generator and assign
the generated sequence to our Order.OrderId
configuring the initial sequence to 1000
. Similarly for Accessory.AccessoryId
where we set the initial value to 2000
. Finally we test by creating an Order and an Accessory where we can observe
the assigned values
of OrderId, AccessoryId.
The SequenceStorage table is a normal XAF BO, therefore it is possible to create sequence bindings in code by creating instances of that object. However we do not recommend creating instances directly but use the provided API (possibly in a ModuleUpdater). The API respects additional constrains and validations.
To generate the configuration of the screencast you can use the next snippet.
objectSpace.SetSequence<Order>(order => order.OrderID,2000);
objectSpace.SetSequence<Accessory>(accessory => accessory.AccesoryID,1000);
To share the same sequence between types use the SequenceStorage.CustomType
member.
To observe the generation results you may use a call like the next one:
SequenceGeneratorService.Sequence.OfType<Order>()
.Do(DoWithOrder)
.Subscribe();
SequenceGeneratorService.Sequence.OfType<Accessory>()
.Do(DoWithAccessory)
.Subscribe();
Limitations:
The module works only for MSSQL, MySql, and Oracle databases.
Possible future improvements:
- Provide logic to allow re-generation of a sequence for e.g. when an object is deleted or per demand.
- Support all database providers.
- Additional constrains e.g. based on view, on model, on object state etc.
- Any other need you may have.
Let me know if you want me to implement them for you.
-
First you need the nuget package so issue this command to the
VS Nuget package console
Install-Package Xpand.XAF.Modules.SequenceGenerator
.The above only references the dependencies and nexts steps are mandatory.
-
Ways to Register a Module or simply add the next call to your module constructor
RequiredModuleTypes.Add(typeof(Xpand.XAF.Modules.SequenceGeneratorModule));
The module is not bound to DevExpress versioning, which means you can use the latest version with your old DevExpress projects Read more.
The module follows the Nuget Version Basics.
.NetFramework: net461
DevExpress.Persistent.Base | Any |
DevExpress.ExpressApp | Any |
DevExpress.ExpressApp.Validation | Any |
DevExpress.ExpressApp.Xpo | Any |
Fasterflect.Xpand | 2.0.7 |
JetBrains.Annotations | 2020.1.0 |
System.Reactive | 4.4.1 |
System.ValueTuple | 4.5.0 |
Xpand.Extensions | 2.202.57 |
Xpand.Extensions.Reactive | 2.202.58 |
Xpand.Extensions.XAF | 2.202.58 |
Xpand.Extensions.XAF.Xpo | 2.202.54 |
Xpand.XAF.Modules.Reactive | 2.202.58 |
Xpand.VersionConverter | 2.202.10 |
To Step in the source code
you need to enable Source Server support
in your Visual Studio/Tools/Options/Debugging/Enable Source Server Support. See also How to boost your DevExpress Debugging Experience.
If the package is installed in a way that you do not have access to uninstall it, then you can unload
it with the next call at the constructor of your module.
Xpand.XAF.Modules.Reactive.ReactiveModuleBase.Unload(typeof(Xpand.XAF.Modules.SequenceGenerator.SequenceGeneratorModule))
The module is tested on Azure for each build with these tests