1

I am developing an engineering application (WPF, C#) that consists of a collection of other programs that perform specific engineering tasks. I guess you can think of it like Microsoft Office, however unlike MS Office, the programs within the application all share the same context in that the tasks that they perform all relate to a single job. So just to clarify, imagine I have a job that is the design of an office building. My application would have a collection of programs that perform different engineering calculations relating to the design of the building. Imagine I have a program that designs the footings, a program that designs the beams/columns, a program that calculates loads etc etc. All these programs I call 'design modules', and my main application simply acts as a landing page for all the design modules. It also stores job specific state such job number, address etc.

So to my question. I originally decided to structure my program this way (i.e. a bunch of stand alone programs/design modules that the user can launch from the main application) because I was thinking along the lines that each design module would be a stand-alone application that does not rely on the existence of the other design modules. As I am developing the application, I am realizing that I want to give the user the option to integrate state/data/calculation output generated by each of the design modules more and more with each other. For example, say I generate some loads in the loading module that I want to use throughout the other modules. I need the other modules to be aware of when state changes in the loading module, and to update accordingly. I know i can use some form of IPC to notify other modules when the state changes in another, but I am starting to question the wisdom of my original approach of breaking up the other design modules into separate stand-alone programs. It seems much easier to just create one application and break up the different modules into assemblies, than to break up the modules into separate programs that communicate through IPC.

On the one hand, each design module can truly function independently without relying on state from the other modules, so there really is no absolute need for them to be all be integrated into the one program. The amount of data that can be imported/retrieved from other module outputs is really up to the user. They can use a lot or not at all. On the other hand the best use of the application as a whole would be to have all the design modules work together. They are after all, all trying to design different aspects of the same building, so there naturally is some sort of shared information and intrinsic reliance on the outputs of other design calculations (e.g. if a footing is supporting a column, you need to know the load in the column to design the footing. The user could either manually enter this loading data in, or the footing module could retrieve this data from the column module, if the user chooses).

So my question is what do you guys think the best option is? Keep going with the current approach of having each design module as a separate program, and if required, use IPC to communicate with each other, or just make one single executable without IPC?

Thanks all.

2 Answers 2

3

Why not both?

  • keep your system modular, with the option of executing / using each module on its own

  • have an integrating GUI which allows to call the other modules, and maybe coordinate their interprocessing.

There are several technical options how this can be achieved, depending on the communication requirements of the different modules. I cannot tell you what the most suitable option for your case is, but just to give you some options:

  • Each module could be designed as an assembly of its own, with a class library interface, so it could be called either from a standalone frontend or from your main GUI (in-process). This way, no IPC will be necessary when modules are started from the central GUI, but they can still be used on their own.

  • Modules are started as separate processes from the main GUI. Data exchange between modules can be done by

    • command line arguments (at program start)
    • classic files
    • memory-mapped files
    • a lightweight local database (for example, an SQLite DB)
    • shared memory
    • some http-based local networking protocol
    • an in-memory message broker like Redis
    • ... (add your own ideas here)

In reality, it will probably be a mixture of these.

Going this route can help you building an application which looks like a well-integrated monolith from outside, but still is really modular and unit-testable under the hood.

2
  • At the moment my app is structured as per your option 2. There are other complications of breaking up the modules that I did not mention in my OP e.g shared resources such as images etc. I would need a central place for these assets that all modules can use, rather than make copies of them in the individual module projects. This is a complication that can be avoided by making it a single app rather than modular. I know there are ways you can share resources b/w multiple projects, however I am wondering if there is anything to be gained for the added complexity of breaking up the app?
    – porters
    Mar 19, 2021 at 6:00
  • @porters: resources can be shared the same way like code: by creating common libraries - modules can still be separated and designed as different processes. The most important benefits of strict modularity (specifically for a desktop application) are individual testability and scalability of the development process (changes to individual modules can be done by different persons in parallel, and it requires less integration tests). Another point is robustness: when one module crashes, the main GUI can restart it, and other modules may not be affected.
    – Doc Brown
    Mar 19, 2021 at 6:28
1

Some well-known programs in similar genre often employ "modes": it ranges from generic layout presets to unique specialized views with familiar elements.

You may design each module as a component, that can be embedded into a MDI window or a tab and linked to a shared controller. Allow the user to choose which modules they want to work with, or perhaps make one "start page" with common information and buttons for launching other modules (aka dashboard). You may even end up developing document-based layout (not unlike a browsed or IDE) — pretty easy with something like dragablz.

There is no use splitting one application into multiple, unless you want to ship them separately.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.