KEVOS® Knowledge Library · SolidWorks API Add-in Development
Planning, Structure and Debugging Discipline
The pre-development decisions that are expensive to reverse, the skeleton-first build sequence that exposes design faults early, and the debugging techniques that apply when your code runs inside someone else's process.
- Doc № KL-ENG-COMP-008
- Engineering › Computers
- Part 08 of 10
- 8 min read
- Updated 2026-08-04
01Executive summary
Most engineers who write software can make it work. Fewer structure it so that it stays workable. The gap between those two positions is almost entirely made up of decisions taken before any code is written, and of the order in which the code is then built.
The single most valuable output of planning an add-in is catching an architectural mismatch early. The canonical example in this domain is building a stand-alone client and discovering half way through that the requirement needs notifications — at which point the work already done must be re-hosted. Half an hour of planning would have surfaced it.
02Why plan at all
Planning is not paperwork. It is the cheapest available mechanism for discovering that an approach will not work.
Approach validation
Confirming the architecture can meet the requirement before committing weeks to it. The forcing requirements — notifications, in-process members — are cheap to check and expensive to discover late.
A path you can hold in your head
Knowing the route before you start means you recognise when you have wandered off it, and you can see the consequences of a shortcut before you take it.
Problems surfaced while they are cheap
Design faults found on paper cost minutes. The same faults found after the interface, the persistence layer and the installer have been built cost weeks.
Separation of design from function
Deciding what the product should do, before deciding how, keeps implementation convenience from quietly becoming the specification.
03Pre-development decisions
Four decisions belong before the first line of code, because each one constrains everything after it.
- Language level
Languages trade proximity to the machine against development speed. Assembly gives complete control at the cost of needing to understand the hardware; C and C++ sit close enough to the machine for performance-critical work; managed .NET languages trade a modest amount of that for markedly faster development and cleaner code; scripting and macro languages trade most of it for accessibility.
- Application type
An executable runs directly and suits most stand-alone tools. A library has no entry point and must be invoked by something else — which is exactly what an add-in is. A service runs under the operating system's service host with its own privileges and lifetime.
- Integration model
Add-in, stand-alone or hybrid — the subject of Part 07, and the decision most likely to be regretted if deferred.
- Structure and interface
What the user should see and how information should reach them, sketched deliberately before programming constraints are allowed into the conversation.
| Requirement | Type | Because |
|---|---|---|
| Runs on its own | Executable | Has an entry point the operating system can call |
| Loaded and driven by a host application | Library | No entry point; the host instantiates and calls into it |
| Logic shared between several products | Library | Can be versioned, released and updated independently of any shell |
| Runs before or without an interactive login | Service | Hosted by the service control manager with its own privileges |
Sketch the interface you would build if nothing were constrained, then work through which parts the platform actually supports. Where an ideal is impossible, the substitute is usually obvious once you know precisely what you were reaching for — and you often find a better answer than the one you would have designed defensively from the start.
04The build sequence
Building in this order exposes structural faults while they are still cheap to fix.
- Interfaces first
Main window or page, controls, menu entries — everything the user will see, with nothing behind it.
- Flow next
Wire events to empty methods named for what they will do. Clicking through the product now shows you the flow without any logic obscuring it.
- Function in journey order
Implement in the order a user would encounter the features. Configuration before the thing being configured; data before the reports over it.
- Iterate the interface
Expect to revise the interface once the functionality is real. Doing it as a deliberate pass keeps the design clean rather than patched.
An add-in's slowest cycle is close host, rebuild, reopen host, reload. A skeleton lets you test navigation, page toggling and command placement across a handful of cycles, rather than discovering a layout problem after the logic behind it is written.
05Debugging as a method
Defects come in two shapes: the program stops, or the program continues and is wrong. Both are failures of the code, and the second is the harder of the two because nothing announces it.
1. Set a breakpoint at the earliest point you still trust. 2. Run under the debugger; execution halts before that line runs. 3. Step over - execute the line, including any call, and stop. Step into - follow execution into the call, if source exists. Continue - run to the next breakpoint or to completion. 4. Compare each variable against what you expected it to be. 5. The first divergence is where the defect lives.
- Step over
- The default move. Treats a call as a single operation, which is what you want while you are still locating the fault.
- Step into
- Use once you have narrowed the fault to a specific call and need to see inside it.
- Watches
- For values that change across many lines. Cheaper than stepping and re-reading the same variable repeatedly.
- Conditional breakpoints
- For faults that appear on the two-hundredth iteration. Break on the condition rather than stepping to it.
- Where to start
- The last point at which you are confident the state was correct. Working forward from certainty beats working backward from a symptom.
There is no fixed procedure that solves every defect, and claiming otherwise is dishonest. What can be taught is the habit: form a specific expectation about what the state should be at a given line, then check it. Debugging without an expectation is just reading.
06Debugging inside a host process
Add-in debugging carries constraints that ordinary application debugging does not.
| Constraint | Consequence | Response |
|---|---|---|
| No entry point | The add-in cannot be launched directly | Start the host as the external program, or attach to the running host process |
| Assembly locked while loaded | Rebuild fails until the host closes | Batch changes; keep volatile logic in a separately loadable component |
| Exceptions execute inside the host | An unhandled fault can take a modelling session with it | Guard every callback and notification handler at its boundary |
| Failures may be silent | No dialog, no log, nothing happens | Instrument the connect path so you can see it was reached |
| Host state is not reproducible from a fresh start | Some defects only appear in an established session | Attach to a session already in the state that fails |
Because a failure to load produces no message at all, the cheapest diagnostic in add-in work is a simple, removable signal at the start of the connect method. Knowing whether you are debugging a registration problem or a logic problem eliminates most of the search space in one step.
07Testing beyond your own machine
Software that works on the development workstation has been tested against exactly one configuration — and the least representative one available, because it is the machine that has every tool, every runtime and every registration already present.
08Quick reference
- Plan to answer
- Can this architecture meet the requirement? Everything else in planning is secondary.
- Pre-development
- Language level, application type, integration model, interface structure.
- Build order
- Interfaces, then flow with empty methods, then function in user-journey order, then a deliberate interface pass.
- Debug method
- Break at the last point you trust, step over by default, compare against a stated expectation.
- Host constraints
- No entry point, assembly locked while loaded, exceptions land in the host, failures can be silent.
- Test matrix
- Host release, operating system, privilege level, real data, unfamiliar operator.
09Where this leads
Continue in this pathway
- Part 01Add-in architecture and the integration model
- Part 02Development environment and project configuration
- Part 03COM registration and add-in discovery
- Part 04Command Manager, menus and toolbars
- Part 05Property Manager Pages and the control model
- Part 06Event and notification architecture
- Part 07Add-in, stand-alone or hybrid
- Part 08Planning, structure and debugging discipline
- Part 09Deployment methods and installer engineering
- Part 10Licensing, distribution and commercialisation
