At Brandt Building Services there is a program that nobody likes to look at, but nobody wants to switch off either: the Order Book. Ms. Aydin, the dispatcher, enters the day's orders into it every morning. Mr. Kowalski, the field technician, calls in the evening and asks what is on for tomorrow. The owner, Mr. Brandt, has a simple question: "Does this have to be redone now?"
This lesson does not answer it with yes. It gives you the tool to answer the question honestly for a program of your choice. Sometimes the answer is "yes, step by step", and sometimes it is "no, leave it as it is". At the end, your repository holds an ADR (Architecture Decision Record) with the decision for the Order Book and the paths you rejected. How an ADR is built is covered in K4, module 4.1 (Architecture as a decision). Here you use the template.
What Microsoft says about .NET Framework
Before you talk about costs, you need a few facts. They are in Microsoft's documentation:
- .NET Framework keeps running. It ships with Windows, and there are no plans to remove it. Microsoft states explicitly that you do not have to migrate your .NET Framework programs. New development, however, should happen on .NET.
- .NET Framework gets no new features anymore, but it still gets security fixes. Version 4.8 counts as a component of Windows and follows the lifecycle of the operating system it is installed on.
- .NET gets a new major version every year. Long-term and short-term support alternate. A version with long-term support (LTS) is supported for three years; .NET 10 is such a version. After that it no longer gets security and quality updates. So if you run on .NET, you will also have to lift to the next version regularly in the future, only that is a much smaller step than the jump from .NET Framework (lesson M2.1 and following).
- Windows Forms and WPF exist on .NET, but only on Windows. They are being developed further there: newer controls, better support for high screen resolutions, improvements in accessibility. Some features, such as dark mode on Windows 11, exist only on .NET.
Nothing follows from these statements yet. They only make visible what "outdated" means: The program keeps working, but the platform underneath no longer moves. Whether that is a problem depends on your business.
The five paths
For an existing program there is not "modernize or not", but five paths. This course teaches paths 2 and 3 and the interplay of the two; you need to know the others in order to reject them honestly.
| Path | What happens | In favor | Against |
|---|---|---|---|
| 1. Keep | nothing changes in the program, only care and safeguarding | no risk to behavior, no effort | platform and knowledge keep aging; every change stays expensive |
| 2. Lift to .NET | same features, new runtime (net10.0-windows) |
same user interface, little relearning, security and tools current again | remains a Windows program; the design (business logic in the form) stays |
| 3. Rebuild | pull out and replace business logic, data and user interface step by step | every stage delivers value, the legacy program keeps running | long phase with two worlds; needs discipline and a safety net |
| 4. Rewrite | a new program from scratch, the old one runs until the switchover | clean architecture, free choice of technology | all rules have to be found again; the switchover day carries all the risk |
| 5. Replace or retire | use standard software or a service, or the task goes away | no code of your own anymore | customizations, data migration, dependence on the vendor |
The paths do not exclude each other. The Order Book in this course takes path 2 and then path 3: First it runs unchanged on .NET 10, then you pull something out piece by piece. Both steps can be stopped if the situation changes.
flowchart TD
A[Does the program do its job?] -->|no, the task goes away| E5[Path 5: retire]
A -->|yes| B[Is there a suitable standard product?]
B -->|yes, covers the rules| E5b[Path 5: replace]
B -->|no| C[Does it have to change or grow?]
C -->|no, runs on a supported system| E1[Path 1: keep and safeguard]
C -->|yes| D[Is there a safety net and the source code?]
D -->|no| E1b[Path 1: build the net first, then decide again]
D -->|yes| F[Are platform and design the problem?]
F -->|only the platform| E2[Path 2: lift to .NET]
F -->|the design too| E3[Path 2, then path 3: rebuild]
F -->|source code unusable| E4[Path 4: rewrite]
The diagram is a memory aid, not an algorithm. It orders your questions. The answers come from your business.
What "outdated" really costs
"Outdated" is a feeling as long as nobody puts a number on it. Three items are usually meant. This lesson gives no figures for them, because yours are the right ones: Write them into your ADR yourself later.
People. Who maintains the program, and how many people know how it works? At Brandt Building Services it is one: the service provider who built the Order Book a long time ago. New colleagues today learn .NET, not .NET Framework with DataSets. If that one person drops out, the program stands still, even though it technically runs.
Security. Which parts still get fixes? .NET Framework gets security fixes as long as the operating system is supported. But every package you use has a lifecycle of its own: If it is no longer maintained, the hole appears there. Whoever runs on a .NET version whose support has ended gets no security fixes anymore. So ask: Which operating system does the program run on, which packages does it use, and who checks them?
Tools. What can still be built and tested with it? Newer SDKs, templates and language features are available on .NET, and many packages now target only .NET. A program on .NET Framework stays shut out of that. You notice it in small things: a package that supports only the old version, a build that runs on only one machine, tests that nobody writes because the program cannot be tested.
Set against that are the costs of a rebuild. They are not smaller, only better hidden:
| Item | Question |
|---|---|
| Work | How many people over how many weeks, alongside the daily business? |
| Risk | What happens if the behavior changes? Who notices first, Ms. Aydin or a test? |
| Dual running | How long do old and new run side by side, and who maintains both? |
| Forgoing | Which feature that the business wants stays on the shelf during this time? |
| Learning | What does the team have to learn (web, Azure), and who teaches it? |
A rebuild is an investment, not an end in itself. It pays off when the item "cost of doing nothing" grows larger than this list. Microsoft recommends ordering upgrades by risk and return: first a targeted assessment, then a pilot on a project with low risk, and with the results the larger planning. This is exactly how this course is built, and M1 is the assessment.
Eight questions, one path
With these questions you arrive at a recommendation that can be justified. Answer each with yes, no or "unclear". An "unclear" is a work order for lessons M1.3 and M1.4.
| No. | Question | Yes favors | No favors |
|---|---|---|---|
| 1 | Should the program change in terms of business over the next few years? | path 2 or 3 | path 1 |
| 2 | Does the business depend on it running without interruption? | path 3 (old and new side by side), not path 4 | any path is conceivable |
| 3 | Do you have the source code and can you build it? | path 2 or 3 | path 5, or first path 1 with a safety net |
| 4 | Is there a safety net (tests, a database copy, a description of the behavior)? | path 2 or 3 | build the net first (module M2) |
| 5 | Does more than one person know the program? | path 1 is sustainable | paths 2 and 3 reduce the risk of a dependency |
| 6 | Is there a product on the market that covers the business's rules? | check path 5 | path 2 or 3 |
| 7 | Should the program also be usable outside the office (browser, phone)? | path 3 | path 2 is enough |
| 8 | Does it run on an operating system and with packages that still get fixes? | path 1 is defensible for now | path 2 right away |
Two answers you should not skip. Whoever answers question 3 with no can hardly apply this course's pattern: Without source code, nothing can be pulled out. And whoever answers question 4 with no should not rebuild anything yet. Lesson M2.1 (The safety net first) builds this net.
When you had better not modernize
That, too, is a good decision if it is justified. Good reasons are:
- The program does its job and does not change. A program that has run unchanged for years, on a supported system, with no known holes, costs next to nothing to operate. A rebuild would buy risk where there was none.
- The task is going away soon. If the line of business that the program supports ends in the foreseeable future, path 5 applies: retire it.
- Standard software covers it. Then the path is not "modernize" but "replace", with data migration as the main work.
- Every prerequisite is missing. No source code, no build, nobody who knows it: Then you begin with path 1 and first build the safety net. The documentation on the strangler fig pattern (lesson M1.4) says the same: The pattern does not fit if you cannot change the legacy system.
- The team has no capacity. A rebuild that stalls after two weeks because of daily business leaves two half programs behind.
What you do in any case, even for "keep": Make sure the source code is in a repository, that it can be built, that a backup of the database exists and that a second person knows how the program is delivered. That costs little and keeps all paths open.
The ADR: We modernize the Order Book
Brandt Building Services has answered the eight questions: Dispatch wants access from the phone too (7), the program has only one
maintainer (5), the safety net is missing (4), the source code is there (3), and the business must not stop (2). With that, the decision
is no longer a matter of taste but can be written down. The ADR lives in the repository at docs/adr/0001-modernize-the-order-book.md;
the full version is in the solution to Exercise 2. Its decision in one sentence: first lift to .NET 10, then rebuild step by
step, run old and new side by side, and switch the legacy program off only when the measurement allows it.
An ADR is only as good as its alternatives. That is why this one contains five options, one per path, each with its best argument, not as a straw man. The trade-offs name what Brandt Building Services gives up: In the next few months no new features appear, and the team has to learn web and Azure.
What can go wrong
- The straw man. The option "Rewrite" is written down only to make the rebuild look better. Test every option with the question: Would you take it if the circumstances were different? If not, it is not a real option.
- Technology instead of benefit. "But it's .NET Framework" is no reason to disturb the business. Justify every path with a consequence for the business: time, risk, security, cost, people.
- Rewriting as a reflex. The business logic of a grown program is written down nowhere, it lives in the code. A rewrite has to find all of it again. Path 3 keeps it and moves it piece by piece.
- Doing nothing is invisible. The costs of path 1 appear on no invoice until something breaks. Write them down.
- Only technology at the table. Ms. Aydin knows the rules she works by every day better than the source code does. Whoever does not ask her changes the behavior without noticing.
- Invented numbers. A calculation with numbers that nobody can back up convinces for one meeting and does harm afterward. Take numbers from your business or leave the line empty.
Exercise 1
Choose a program you know: from your business or, if you have none, the Order Book of Brandt Building Services (it is built
in lesson M1.2; the description above is enough here). Create docs/decision-questions.md in your repository and
answer the eight questions with yes, no or "unclear", each with one sentence of justification. Below that, write which of the
five paths you provisionally choose and which answers you still have to clarify.
How to check your result: Every answer is justified, and every "unclear" names who or what would supply the answer.
Solution 1
For the Order Book, the file could look like this:
# Decision questions: Order Book
| No. | Answer | Justification |
| --- | --- | --- |
| 1 | Yes | Dispatch wants to see orders from the phone too and to model new kinds of maintenance. |
| 2 | Yes | Without the Order Book, Ms. Aydin cannot dispatch in the morning. |
| 3 | Yes | The source code is on the service provider's machine and is being taken into this repository. |
| 4 | No | There are no automated tests and no known backup of the database. |
| 5 | No | Only the service provider knows the pricing rules in detail. |
| 6 | Unclear | Mr. Brandt is checking whether a trades software package covers the maintenance contracts. |
| 7 | Yes | Mr. Kowalski wants to read the plan on the road. |
| 8 | Unclear | Operating system and packages will be recorded in lesson M1.3. |
Provisional path: 2, then 3. Clarify first: question 6 (Mr. Brandt), question 8 (inventory), question 4 (module M2).
Question 6 stays open, and that is fine: If the trades software covers the rules, the decision tips to path 5. That is exactly why you write the questions down.
Exercise 2
Write the ADR for your program (or the Order Book) as docs/adr/0001-modernize-the-order-book.md following the template from
K4, module 4.1: Status, Confidence, Context, Options, Decision, Trade-offs, Consequences, Security and privacy consequences,
Revisit when. The rules there apply: at least two real options, "leave it as is" included; the trade-offs name what
is given up; "Revisit when" names an observable event, not a date.
How to check your result: Read only the "Trade-offs" section. Can Ms. Aydin tell from it what she will not get in the next few months? And do all five paths appear?
Solution 2
# 0001: Modernize the Order Book
- Status: accepted
- Confidence: medium
## Context
The Order Book of Brandt Building Services is a Windows Forms program on .NET Framework 4.8 with DataSet and ADO.NET against SQL
Server. Ms. Aydin dispatches with it every day; Mr. Kowalski wants to read the plan on the road, too. The program is maintained by a single
person, the source code is available, there are no tests. The business must not stop. .NET Framework gets no new
features anymore, and Windows Forms runs on .NET only on Windows.
## Options
### Option 1: keep and safeguard
The program stays as it is; source code, build and database backup are secured. No risk to behavior and no
effort, but access from the phone remains impossible and every change stays as expensive as today.
### Option 2: only lift to .NET 10
Same features, new runtime. Tools, packages and security updates are current afterward, the user interface stays familiar. The
program remains a Windows program with business logic in the forms.
### Option 3: rebuild step by step
First lift, then move business logic into a tested library, data to Azure SQL, replace orders and customers with a web API and
Blazor pages, run old and new side by side, switch the legacy program off last. Every stage delivers value, but there is
a long phase with two worlds.
### Option 4: rewrite
A new program from scratch, switchover on a cutover date. Clean architecture, but all pricing rules and special cases have to be
found again, and the cutover date carries the entire risk.
### Option 5: replace
A trades software package from the market. No code of our own, but the maintenance contracts and pricing rules would have to be adapted or given up,
and the data migration is untested.
## Decision
We take option 3, beginning with option 2, because only it brings the business value early (access from the phone), divides the risk into
small stages and keeps the legacy program as a fallback until the end. Option 5 is being checked in parallel.
## Trade-offs
In the next few months no new features appear in the Order Book. The team has to learn web and Azure, and for a
while it maintains two programs. The goal "fast new features" pays for this, and operating costs rise during dual running.
## Consequences
First a safety net is built from tests and a copy of the database. Every stage gets one commit per step and a
fallback plan. The legacy program is switched off only when the measurement of the pilot group allows it.
## Security and privacy consequences
The customer data (names, addresses, phone numbers) moves into a cloud database and becomes reachable over the web. Sign-in and
permissions must be in place before the first release; secrets are never in the repository.
## Revisit when
Option 5 finds a product that covers the maintenance contracts and pricing rules, or when the first stage takes twice as long as
planned.
Note what the ADR does not do: It names no numbers that nobody can back up, and it records the rejected paths. A year from now, someone will know why option 4 was not chosen.
What you can do now
- You tell the five paths for an existing program apart and know which ones the course teaches.
- You name what an outdated program costs, and what a rebuild costs.
- You answer eight questions to justify a path, including the path "better not".
- You record the decision with its alternatives in an ADR.
In the next lesson you build the Order Book yourself, so that you know every place where something will break later.
Further reading
- Overview of upgrading .NET apps: when an upgrade makes sense, the paths and the recommendation to proceed by risk and return.
- Overview of upgrading Windows Forms apps: why and how Windows Forms programs are lifted to .NET.
- .NET releases, patches, and support: the support periods of .NET.
- Lifecycle FAQ - .NET Framework: how .NET Framework 4.8 is supported as a component of Windows.
- What's new in .NET Framework: the note that .NET Framework ships with Windows and programs do not have to be migrated.
- Maintain an architecture decision record (ADR): structure and upkeep of an ADR log.