I’m currently heavily involved in leading a project to develop a corporate framework for a company that manufactures aircraft components. The project’s medium-term goal is to give the company the fundamental pillars on which to build all its ERP functionality and business processes—an ambitious undertaking.
What do this project (or this company’s needs) have in common with other similar systems? I’ve encountered this situation before: a business moving quickly, with needs that also evolve overnight.
To be more specific:
- Different user profiles need to access the system according to their roles (manufacturing operators, executives, sales, human resources, and so on).
- Everything needs to be integrated into one project that serves everyone. Nothing is worse than needing a collection of scattered, independent applications to feed the business. That makes any kind of analytics impossible—or very expensive—and prevents management from having a clear view of day-to-day operations.
- Needs change constantly, so new functionality must be added frequently. That’s inherent to the system.
- The business will depend entirely on this system, which carries enormous responsibility (we’re talking about millions of euros in revenue—gulp…).
How should we approach this kind of development?
I’ve already been through a similar project where, against my advice, an overly ad hoc and monolithic architecture was proposed to meet these needs. For a system like this, a better approach is to build a component-based architecture (hence the term corporate framework) and keep its technologies as decoupled as possible. For a project expected to run for many years, it’s best not to tie it completely to a single data repository or web technology. In this case, we’re using .NET Framework, but we’ve left everything ready to use .NET Core as soon as it becomes more mature—which will undoubtedly happen as it gains adoption.
This architecture isn’t new: many market solutions use it, directly or indirectly, from content management systems such as Drupal (which extends its functionality through modules) to the functional extensibility of Alfresco. In other words, there’s a framework, acting as a core, that provides base functionality which can be extended with plugins, extensions, components, or modules. The names are interchangeable; the concept is what matters. For this article, I’ll call them all “components.”
What does the base framework do?
It handles the following:
- User management (login, activity logging, creating and deactivating accounts, and so on).
- Everything related to security (roles, permissions, authentication, API tokens, and so on).
- Abstracting away the type of data repository used. Components shouldn’t even need to know whether the underlying persistence layer is SQL Server, SQL Azure, MySQL, Oracle, Redis, or something else.
- The presentation layer: the framework handles the basic process of building the user interface, which is usually based on some web technology.
- Providing an API through which components can extend its functionality. This is essential and the very reason the framework exists.
- Allowing components to be enabled, disabled, installed, or uninstalled at runtime.
- Allowing new components to be added without temporarily stopping the system, ensuring 24/365 operation (except during updates to the framework itself, of course). This makes a DevOps approach possible for the company.
- Assisting components as they move from one version to another, making migrations—and their implementation—as easy as possible.
- Scaling: multiple instances of the framework can run on different servers to provide redundancy and support heavy workloads.
Easy to say, but not so easy to implement.
Thanks to all of the above, a component can:
- Add new functionality to the system (new exportable data entities, recurring tasks, events, views, reports, and so on).
- Be easy to implement, since the framework does much of the heavy lifting. There should be a component development guide so any developer can extend the functionality.
- Include a user interface through a view or block that the framework renders in some way.
- Define its data storage needs without dealing with the details of creating entities, tables, indexes, and so on for the chosen technology—that’s the framework’s job.
- Communicate with other components.
Such a system consists of the framework itself, a set of its own components (core components), and another set of user components (user components). For the project we’re working on, we’ll probably end up with more than fifty components to implement all the required functionality.
Needless to say, for a project of this nature, the framework must be a robust piece of software, with very high test coverage and an impeccable, clean, maintainable design.