Welcome to the series of posts, describing the library, I've been working on for a couple of years. It's name is Navitski.Crystalized.Model
.
A couple of years ago, I started to work on the budget management application. It was a toy project which supposed to help me to practice skills in developing software architecture and give me an opportunity to learn, how to develop applications from the scratch.
Architecture
I wanted to build my project on a solid foundation so architecture for me was a very important topic. I've heard a lot about DDD so I decided to give it a try and use Hexagonal architecture. According to the Wikipedia:
The hexagonal architecture, or ports and adapters architecture, is an architectural pattern used in software design. It aims at creating loosely coupled application components that can be easily connected to their software environment by means of ports and adapters. This makes components exchangeable at any level and facilitates test automation.
So the core of our application will be a domain model, which has no external dependencies and provide some interfaces which will be used to contact the outside world. For example, a domain model wants to read data and modify it using some business rules. To archive that domain model have an interface called, for example, IDataSource
with method Read
. When this domain model will be integrated into the application IDataSource
interface will be implemented by some of the infrastructure modules. Domain model will never know, from where data came from, it will only use its IDataSource
interface. In the following picture, you can see what the Hexagonal architecture looks like:
All right, we know how to make a call to the databases, send requests to internal systems etc. But how to handle an application state, how to create and handle domain model. In terms of desktop applications or mobile applications, domain model should have a number of traits, such as: ability to undo or redo changes made on that domain model, keep application state consistent when an exception is thrown, ability to save and load whole domain model to file or database, be able to notify the rest of application when domain model is changed and provide detailed definition of changes and so on.
Solution
To solve such problems, I've built the Navitski.Crystalized.Model
library. It gives you all you need to easily create your domain models that will have the following features:
- Undo/Redo support.
- Saving/Loading your domain model to the SQLite database or Json file (more storage options can be added quite easily). No need to write all the database logic yourself.
- Precise changes tracker which will tell you exactly what was changed (no need to parse the whole domain model graph by yourself).
- Everything is strongly typed (the source generator will generate everything for you).
- The library and source generator are targeting .NET Standard and .NET 7 so you can use it in the old .NET Framework projects.
- No 3rd party dependencies.
- DI friendliness (you can register all classes into DI container of your choice)
- Easy to use with plugins (plugins can provide their data which will be integrated into the application state).
- Resilience (application state will not be corrupted by exceptions thrown in the middle of modification).