Cascade is a solution to several problems of data management within front end client apps. It provides a clean, consistent, and familiar API that assists the developer in performing data operations with the server, and maintaining data structures consisting of models and collections with the results.
Cascade is designed to work well with existing dotnet UI frameworks, with or without binding. Cascade is also designed to work with virtually any backend server or store, including multiple, by custom implementation of abstract interfaces.
By following the patterns made easy with Cascade methods, an application gets caching, local data persistence and offline-online network resilience almost for free.
An application built on Cascade uses custom model classes subclassing the provided SuperModel class, and calls methods on a CascadeDataLayer class instance for all operations. Serialisation/deserialisation happens mostly automatically using System.Json.Text but the application code only operates with models. Building an application on this layer means isolation from server implementation details and changes. Testing can be easily performed on application code using a mock server implementation.
-
A clean and simple interface, reminiscent of a HTTP client, for application server interactions
-
True offline support for all operations
-
You send and receive models, not JSON
-
easy Get/Query of models with their associations via Populate method/parameter
-
seamless multilayer caching & persistence, including collections and queries
-
Optional memory caching for speed
-
Optional file system caching/persistence
-
Supports almost any API server(s) through your own implementation of abstract interfaces
-
Insulation of application logic from server irregularities and changes
- Mostly Immutable Models (application code should never need to modify models directly)
- Associations (Relations) between models: BelongsTo (Many to One), HasMany (One to Many), HasOne (One To One)
- Pagination including infinite scroll for queries
- Multithreaded internally for performance
- Threadsafe for use in alternative threads, including bindable UI properties only modified on the main thread
- Support for binary blobs eg. images (including caching and offline)
- Support for meta-data about models and blobs
- "freshness" option to determine whether to get data from either a cache or the server
- "fallback freshness" option to silently fallback to a cached data when unable to reach the server
- "hold" option to mark retrieved records for downloading and preservation offline even when caches are cleared
var product = await cascade.Create<Product>(new Product() { colour = "Red" });
var product = await cascade.Get<Product>(25, populate: new string[] { nameof(Product.Manufacturer) });
var redThings = await cascade.Query<Product>("red_products",new JsonObject { ["colour"] = "red" });
var updated = await cascade.Update(product, new JsonObject { ["colour"] = "red" });
await cascade.Destroy(product);
var promoted = await cascade.Execute("PROMOTE",new JsonObject { ["product_id"] = 25 })
await cascade.Populate(product,new string[] { nameof(Product.Manufacturer),nameof(Product.Category) })
- Inherit from the SuperModel base class and use the given GetProperty/SetProperty for its attributes
- Models should be treated as immutable by application code - attempting to set a property throws an exception. All changes are done using Cascade methods (which are propagated through the caches and origin server).
- Implement ICascadeOrigin with an origin class for your server(s)' API
- Construct an instance of CascadeDataLayer with the desired cache layer(s) and origin
- Use the methods of CascadeDataLayer (Create/Get/Query/Update/Replace/Destroy) for all operations with those models