studio status report: 2022-04
month 4 of 2022 was about the greatest weakness of Blazor and more day-job learnings
There are no more known technical blockers in the way of completing the project associated with new version of SonghaySystem.com. This is great news! However, the underside of this news is my discovery of the greatest weakness (to me) of Blazor: Blazor only has one thread even though WebAssembly has more.
As of seven days ago, Dan Roth is optimistic that Blazor will support multi-threading in a near-future release. This should prevent me from looking into things like BlazorWorker [GitHub].
This threading weakness makes me write Bolero code like this:
on.click (fun _ ->
if model.YtSetIndex.IsNone && model.YtSet.IsNone then
YouTubeMessage.CallYtIndexAndSet |> dispatch
else
YouTubeMessage.OpenYtSetOverlay |> dispatch)
What this click
handler is trying to say is that Blazor cannot handle playing a CSS animation, opening an overlay, and retrieve cached data near-simultaneously. Before the data is cached, model.YtSetIndex.IsNone
and model.YtSet.IsNone
are both true
and this click handler is gambling that it will take at least one second to retrieve the data remotely. Why one second? That is the duration of my CSS animation. When I am wrong about the one-second data-retrieval floor, then Blazor innards will block the CSS animation.
day-job learning?
Yes, I have a new day-job after quitting the old one last month. Of course we all say this but for me it is true: this new job is better than the last one. It has allowed me to revisit validation which is the bread and butter of full-stack forms building. Enter FluentValidation [GitHub].
The ‘horrible’ truth about the built-in system featuring System.ComponentModel.DataAnnotations.ValidationContext
[📖 docs] starts with its ObjectInstance
property (which is boxed as object
). this property effectively associates any Validation Results with the object they come from. This implies that there one Validation Context per validation. It follows that recursively validating child objects (or collections of child objects) is not supported.
The response to issue #1133 introduces FluentValidation [GitHub] to me as the solution to this limitation:
public class ProductValidator : AbstractValidator<Product> {
public ProductValidator() {
RuleForEach(x => x.ProductVariants).SetValidator(new ProductVariantValidator());
}
}
public class ProductVariantValidator : AbstractValidator<ProductVariant> {
public ProductVariantValidator() {
RuleForEach(x => x.Prices).SetValidator(new PriceValidator());
}
}
public class PriceValidator : AbstractValidator<Price> {
public PriceValidator() {
RuleFor(x => x.Price).GreaterThan(0);
}
}
RuleForEach
coupled with SetValidator
in FluentValidation is documented.
For more background on the limitations of default .NET validation, see “Recursive Validation Using DataAnnotations.”
to avoid validation, use change tracking
I admit that I am a bit embarrassed to have taken so so long to take FluentValidation seriously which implies that I never thought about the problem of recursive validation in depth for years—what kind of day jobs was I working? (The kind of day jobs with too much legacy code with legacy problems in the way of working something relatively new.)
After FluentValidation is taken seriously, my next serious move is toward Compare-Net-Objects [GitHub]. How did I stay alive so long without this thing! When validation is considered a performance issue then it can be avoided by verifying that the object is unchanged when compared to its last-saved version. Compare-Net-Objects works well in this scenario and is my lightweight answer to a full-blown change tracking system like the one I have enjoyed in years past in Entity Framework.
selected month 04 Studio notes
Change-tracking in .NET
- The
IChangeTracking
Component Model interface is foundational in .NET [📖 docs]. IRevertibleChangeTracking
extendsIChangeTracking
by adding support for rolling back the changes [📖 docs].- Entity Framework has its own change tracking subsystem.
- TrackerDog [GitHub] depends on declaring all public properties as
virtual
[📖 docs]. This project has not been touched for years. - ChangeTracking [GitHub] also depends on
public virtual
properties but has been touched more recently than TrackerDog. PropertyChanged.Fody
[GitHub] depends on implementingINotifyPropertyChanged
.PropertyChanging.Fody
[GitHub] depends on implementingINotifyPropertyChanging
[📖 docs].- TrackChange [GitHub] is built on top of Fody and only requires the attribute,
[Tracking]
.
You can also implement a change tracker to keep track of everything for more complex scenarios. The change tracker might have a list of the changes—listing property names, values, and timestamps as needed—internally. You can than query this list for the information you need. Think of something like the [Event Sourcing] pattern.
I will need AutoMapper primarily for tests
AutoMapper supports cloning: https://stackoverflow.com/a/34279923/22944
Bogus is a simple fake data generator for .NET
Bogus GitHub is unit-test companion for shipping code with validation logic. By the way, I did have the day-job opportunity to compare Bogus to AutoFixture. The only advantage AutoFixture has over Bogus is its ability to generate random data by default. Bogus requires a rules engine to generate anything but this is better out of the box than what AutoFixture presents because the rules work well with validation unit tests.
Once AutoBogus [GitHub] is coupled with Bogus then I am pretty much set.
roll up of my .NET forms-building tools
When the day-job folks turn down some third-party vertical like Forms.io, then I will immediately need these:
package name | Nuget URI | GitHub URI |
---|---|---|
FluentValidation | https://nuget.org/packages/FluentValidation | https://github.com/FluentValidation/FluentValidation |
FluentValidation.AspNetCore | https://nuget.org/packages/FluentValidation.AspNetCore | https://github.com/FluentValidation/FluentValidation |
Compare-Net-Objects | https://www.nuget.org/packages/CompareNETObjects | https://github.com/GregFinzer/Compare-Net-Objects |
Bogus | https://www.nuget.org/packages/Bogus/ | https://github.com/bchavez/Bogus |
AutoBogus | https://www.nuget.org/packages/AutoBogus/ | https://github.com/nickdodd79/AutoBogus |
AutoMapper | https://www.nuget.org/packages/AutoMapper/ | https://github.com/AutoMapper/AutoMapper |
sketching out a development schedule (revision 20)
The schedule of the month:
- complete project associated with new version of SonghaySystem.com 📜🚜🔨
- generate Publication indices from LiteDB for
Songhay.Publications.KinteSpace
- use the learnings of previous work in Bolero to upgrade and re-release the kinté space 🚀
- convert Day Path Blog and SonghaySystem.com to HTTPs by default 🔐