Introduction
Rengine is a low-level, infrastructural framework that serves as the skeleton for creating complex and multi-functional projects. It is rather flexible, expandable, and may be modified according to the project needs. The main idea of the framework is to significantly reduce the complexity and development time for common case scenarios by simplifying frequently used operations and creating ready-to-use modules. The framework provides the following functionality:
-
Business objects creation and initialization with cloning capabilities.
-
Business objects loading from a data storage with filtering, sorting, paging capabilities. It allows to load only necessary object properties, thus increasing performance and reducing the payload size. It simplifies the loading of child records with all types of relations (one to one, one to may, many to many).
-
Business objects saving to a data storage with validation. It allows to save only necessary object properties, thus increasing performance and reducing the payload size. It simplifies the saving and validation of child records with all types of relations (one to one, one to may, many to many).
-
Reach validation capabilities. FluentValidation, validation attributes and custom validations may be used. Validation messages may be attached to each business object property, thus making validations user friendly. It is also possible to compare new and previous version of each business object.
-
Seeding data from excel, csv files (other formats may be added if needed). This functionality allows to read a file and populate the data into the data storage. It will take into consideration file modification history and won't update unmodified records. Seed may be used to update the data on production environment or populate test data on test and development environments, which will be useful for QA and development purposes.
-
Localization capabilities. Each text value may be stored using multiple languages.
-
Security subsystem. It includes users, roles, actions (permissions and restrictions) and authorizations, that will grant or restrict certain user operations.The framework has integrated Auth0 and Azure Active Directory B2C identity providers that meet all modern security requirements and allow multi-factor authentication. It is also possible to integrate other identity providers, including standalone, that you may install on your own server.
-
The framework supports Microsoft SQL Server and PostgreSql database management systems. It is also possible to integrate additional database management systems if needed, including non-SQL databases. The framework uses Entity Framework Core, Linq2Db and Automapper under the hood, to reduce code complexity and get rid of writing unnecessary SQL code. But it doesn't limit a developer - custom SQL code or SQL procedures may be added if necessary.
-
Chronicles. The framework may track business object modifications and store the history of those modifications and their authors.
-
Logging. All user actions, errors, warnings, trace information may be stored if needed. The framework may use different log storages (standalone or cloud bases).
-
Because it is a low-level framework, it doesn't impose any restrictions on the architecture of the application. It may be a monolith, a micro-service architecture, or even serverless functions. It may work with different databases, message brokers, loggers, identity providers and other external services.
The main idea of architecture is to divide the functionality into independent layers and handlers (mediator pattern). Each level is strictly specialized and performs work in a specific area. Functionality from one level should not in any way affect the functionality of another level. It is not allowed to directly access internal resources of another level. Instead, you should make a request to another level and get a response.
Such architecture allows to create scalable and fault-tolerant applications. Handlers are building bricks from which you can assemble several micro-services or one major service, depending on project needs. The absence of dependencies between handlers and layers makes it easy to make changes to the business logic of the application.