Basically that’s your generic Client-Server application that heavily relies on the Inversion of Control/Dependency Injection (and the inherent pluggability because of that) and uses the composite application approach for the client UIs (supported by the distributed model).
Note, that the different types of UIs share the same in this structure. Web UI is just another type of interface, and thus there could be a number of those running around the single server (another way to balance load between the web applications). For some situations the Web UI could be directly coupled with the server (i.e.: when the server is hosted in the IIS), but logically they would stay separate.
Another requirement specifics lies within the extensibility approach common to all business frameworks. That’s the “Don’t Repeat Yourself” principle. Basically if some functionality is going to be reused and it could be efficiently made reusable, then this should be done. For example this could be done with the generic grid handlers or the configurable editor handlers (and then the reflection and configuration could do the rest). Things like controllers and workflows theoretically could be made generic and configurable, but it is just not worth the effort (no, I do not like the Windows Workflow Foundation).
Note that in this scenario there is no Security/Permissions block. That’s because sprinkling the CurrentAccount.IsInRole(“Admin”) or CurrentAccount.For(currentProject).Can(“Print”) all other the UI code is a bit inefficient and complex for my taste (and using policy injection with the castle is still too heavy for the maintenance). So for the core framework all the security is based on the views (although this could be extended).
Views and handlers
The user has access to the pre-configured views that are handled by the appropriate UI handlers in the corresponding UI. So basically if there is message board functionality that is supported by both the Web-UI and desktop UI, then we could configure it only once in the navigation tree. And then the corresponding UI will just pass the configuration to the appropriate handler. And the configuration will explicitly tell the handler how it should behave and look.
So what about the security? Although the communication channels are easy to secure, the client still could be simply hijacked or hacked. From the security point of view, the views just *hide *illegal actions and options. And the server is actually responsible for enforcing security. Its architecture makes sure that all the critical resources are secure.
Whenever a handler on the client side wants to do something specific with the database or any other resource, it talks either to the data gateway service or its own service implementation.
The data gateway interface handles generic access to the back-end data-store with the basic security checks based on the data schemas. Basically, it answers this question: “Can this user C/R/U/D these records while working with these columns?”. And if he is not allowed to (either the client is hacked, or the malicious component has been installed or the administrator has forgotten to hide that “delete” button from that view), then there will be proper log entry made and the exception will be passed back to the client.
Additionally the gateway supports distributed caching and support for the server-side filtering, grouping and ordering of the dynamically constructed client queries.
If there extra functionality needed on the client side, then here are the primary extension options:
- Implement client-side custom handler that uses services/components registered in the kernel
- Implement client-side custom handler and the custom client services that talk directly to the data gateway
- Implement custom gateway service on the server that talks to the secure server components. It should be exposed and consumed by the custom components and handlers on the client.
In all these three scenarios communication with the data storage (and other critical services) goes only through the secure core API (and it brings all the logging/audits, base security etc along). So, for example, if the audit tables have been explicitly blocked, the extensions will never have access to them.
Note, that the data gateway initially provides only schema-based protection. So if there is need for finer-grain control (like ACL lists) then it would have to be implemented separately. Once this is done, the new functionality could be reused in other services as well.
These logical restrictions are explicitly stated up-front (along with the other requirements). Following them may constrain the development_ tactics, but the overall development _strategy will lead to the efficient and maintainable flexibility.
Note, that this solution definition is not something solid. It constantly evolves as the new requirements are being passed from the customers. Some of those go into the extensions, and some even affect the core.
Additionally, the actual implementation requirements are too numerous to be listed in this short article. Some other things that are just being considered but nonetheless affect the architecture and development:
- Possible support for hosting xLim servers natively in Linux environments
- Possible future support for the Linux desktop clients, etc
- Using dedicated task engines and notification services for hosting heavy workflows and integration with the 3rd party systems
- Support for the efficient server load balancing (i.e.: file store could be moved to a separate server, some extension services could host their data on the external repositories, etc)