all Technical posts

Advanced and Realistic Domain Model Validation Building Blocks in F# FPrimitive with C# Interop

Model validation is a big and important topic. Lots of application security issues are related to input validation. See how FPrimitive transcends simple validations and can be used in more advanced scenarios.

FPrimitive is a F# library of mine with full C# support. It handles all kinds of model validations by defining specifications for your model. In this blog post, I’m going to assume that you have a basic understanding of the library and of domain model validation. If not, I recommend a couple of my other posts to get you started.

Optional Types

Optional types are types that are part of the model but are not necessary to create a valid model. In the context of Corona, let’s create a model with such an example. Consider a guest at a concert that has to show his Corona Pass before entering. The guest either has or hasn’t a pass with them, but still remains a ‘valid’ possible guest.

You’ll see that the pass is optional here to create a guest model. With the FPrimitive library, we can easily model this with the Spec.optional function. In this case, we use the Option.ofObj to determine if the incoming `string` is null. In that case, None will be used. The Union.create function is also available in the FPrimitive library and lets you create Discriminated Unions based on string values. It creates an Result based on the result, which makes it perfectly combinable with the specification functions.

With the Spec.optional you can therefore choose to only validate a certain input when a function ('a -> 'b option) holds. It makes it a good specification combinator for optional types while doing domain modeling.

Invariants

Domain invariants are relationships within the model. Rules about two or more sets of models. This relationship should also be expressed fluently and descriptive in the domain. FPrimitive made this happen. The Spec.invariant takes in two specifications and creates a new specification of the combination. There are is also a function to take in 3 specifications. If more is needed, the system is flexible enough to create any more combinations you want.

A good and simple example of such an invariant, is designing a range model with a minimum and maximum value. The domain invariant in this case will make sure that the minimum is always smaller than the maximum value.

Dependencies

Dependency validations in the context of domain modeling will make sure that a dependency is validated before the main validation. This concept is important when handling rather complex validations and/or you want to re-use specifications. In that case, FPrimitive has several combinators that let you define specification dependencies that will run before the specification you define.

Imagine you want to model that represents a series of text. There will often be similar things that you need to check, such as blank input, special characters. In those cases, we can make use of the dependency validation.
This makes for great re-use of specifications.

Conclusion

In this post I’ve barely scratched the surface of domain modeling with FPrimitive. There are a lot of advanced combinators to describe complex models. Spec.structure, Spec.filter, Spec.subset, Spec.listetc. are all great combinators too, but that will be for another time.

Please consider F# in your next project, even if it’s just for domain modeling and internal business rules. I strongly believe that the combination of F#/C# is the sweet spot we’re all trying to find.

Thanks for reading!
Stijn

P.S. Here’s what this looks like in C#:

Subscribe to our RSS feed

Thanks, we've sent the link to your inbox

Invalid email address

Submit

Your download should start shortly!

Stay in Touch - Subscribe to Our Newsletter

Keep up to date with industry trends, events and the latest customer stories

Invalid email address

Submit

Great you’re on the list!