Monday, May 05, 2025

19 Questions to ask before migrating a Xamarin app to .NET MAUI

Xamarin Logo, right pointing arrow, .NET MAUI logo
I got asked about helping rewrite a "legacy Xamarin-based mobile app to .NET MAUI". They'd already determined how long it would take, but had very few details about the app or the rewrite/migration.

To help anyone else in a similar situation, here are a few questions to ask (and get answered) to determine how much time/effort will be required in such a project.
  1. What's driving the rewrite?
  2. What's driving the time scale for the rewrite?
  3. When was the code written initially?
  4. Who has been maintaining and updating the app since it was originally written?
  5. What does the existing app do?
  6. How is the existing app built?
  7. How is the existing app distributed?
  8. How is the existing app tested?
  9. Does the initial code base use Xamarin.Forms or Xamarin Native?
  10. Which platforms (operating systems) does the existing app run on?
  11. Does the application have any specific customisation or variation in functionality when running on different devices or operating systems?
  12. What programming languages does the existing app use?
  13. How large is the existing app?
  14. What 3rd party controls or tools does the existing app use?
  15. How are 3rd party tools licensed?
  16. Do the 3rd party tools have equivalent support for .NET MAUI?
  17. What external systems (including back-ends, analytics, etc.) does the existing app connect to?
  18. Beyond getting the app to build and run with .NET MAUI, what other changes are planned and/or needed?
  19. What are the long-term plans for the app? (Who's going to maintain and update it after this rewrite?)


Obviously, the answers to many of these questions will prompt follow-ups to identify relevant specifics.

What did I miss?

Friday, May 02, 2025

My second rule of testing

For a long time, I've told people that I recommend adding tests for any code that is "non-trivial".

I define non-trivial to mean any code that you can't look at and immediately see all the possible paths through it and potential outputs, such that you can see that all possible negative and edge-case consequences are correctly handled. Yes, the reality is that very little code meets this threshold.

I also make exceptions for plumbing code.

2
I now have a second rule. Well, guideline:

Include tests for anything that may be affected by a change in a dependency.

This matters because dependencies change and get updated. Without tests to verify that nothing has broken or been altered in unwanted ways, switching to using a new version of a dependency is a bigger risk than it should be or that you probably want to have to deal with.

Oh, that package you use now has a new version that reportedly fixes a security vulnerability. How quickly can you switch to using the new version? Do you trust that there are no other changes or consequences of updating? Can you be sure? Do you have the time to verify manually?

Also note that this applies to both internally and externally sourced dependencies.


Friday, April 25, 2025

Agentic programming makes me want to stop programming and also do it more

TLDR: Using agents for programming can be great, but I fear for the maintainability of the code that's produced. As I'm currently looking for work, this lets me see the value my experience can bring, while also making me fear a future to having to work with a lot of code that was quickly written but is mediocre (at best) and hard to maintain.

Tuesday, April 22, 2025

Three types of technical debt

Let's compare technical debt and real-world financial debt. (Aren't I "fun"?)


TL;DR:  Many developers are creating future problems for themselves because they're not thinking about the consequences of their actions. For some languages and technologies, the examples aren't great and don't teach everything that's needed to avoid future problems.

credit card, shark, question mark

I'm going to consider three broad categories.


1. Credit card - make a deliberate choice to put something off (paying for an item/service) knowing that will have to come back to it (& pay) later, possibly with some interest.

Having a little of this is normally not a problem.


2. Loan shark - No other options when you have to do something now. It's solving a short-term problem but likely creating a bigger and more expensive one for the future.

Avoid as far as possible. (If you're in real financial debt, please talk to someone--don't struggle alone.)


3. Financially illiterate - No one ever taught you about money or saving. You spend money without thought, have multiple store and credit cards, have little or no savings, and live "pay-check to pay-check".

"This must be fine", or so you think. "Doesn't everyone live like this?" "I'm sure it will all work out in the end--somehow."


Hopefully, the comparisons are clear.

What the term "illiterate" might hide is that this isn't always the developer's fault. 

Some languages/technologies/frameworks are taught in only the most basic ways. The student is shown how to get started or do the basics, but the instructions never go beyond that.
Even examples and so-called "best practices" don't help. "Expert" code looks like beginner code, and not in a good way.

Everyone makes the same mistakes, builds up a code base with the same issues, and talks about the code/language/framework with the same complaints.
Eventually, the problem becomes clear, and someone suggests a rewrite with a different technology.

It sounds like declaring financial bankruptcy, and that future financial problems will be avoided by only trading in cash/gold/crypto. 

Is it the technology/medium that's the problem? Or is it how it's used?


If you're learning, are you learning how to do something without creating future problems for yourself?

If you're teaching, are you setting up your students for long-term success?

If you're creating a language/technology/framework, are you doing so in a way that encourages doing things in ways that avoid long-term problems?



Friday, April 11, 2025

Choosing a framework to build a native app on Windows with .NET

"Thinking face" surrounded by logos of different frameworks

By "Native," I mean not using web technologies, either as a remotely hosted website or bundled into a package that is installed and runs locally.

Let's get this out of the way first. 

There is no "best". 

There is only best for your current circumstances and requirements at the current time.


That said, how do you decide what might be best for your circumstance?

Each option has slightly different capabilities. It's essential that you know what capabilities you'll need before you start building. If you don't know what you need to build, it's impossible to say which is best for you. This may make the decision for you. 
Doing the work in advance to fully understand the requirements can save a lot of frustration and wasted time and effort if you discover you need something the framework can't do. 

So, second disclaimer out of the way, how do you decide which .NET framework to evaluate first? 

If the first thing you evaluate does all you need, it's probably fine to go with that. If not, try another.


Q1. Do you think you might ever need to run on more than just Windows?

If Yes - go to Q2.

If No, go to Q4.


Q2. Do you want the software to also run on the web?

If Yes - Evaluate UNO Platform first.

If No - go to Q3.


Q3. Are you primarily interested in building an app that runs on desktop, or on mobile devices?

If Desktop - Evaluate Avalonia first.

If Mobile - Evaluate .NET MAUI first.


Q4. Do you already have any existing apps built with WinForms, WPF, UWP, or WinUI?

If Yes - continue using that. (Unless it's UWP, then go to Q7.)

If No - go to Q5


Q5. Are you building a "traditional line-of-business" app or something that could be described as "forms over data"?

If Yes - go to Q6.

If No - go to Q7.


Q6. Are you happy to use/learn XAML?

If Yes - evaluate WPF first.

In No - evaluate WinForms first.


Q7. Do you need to support XBox devices, game pad controls, or ink-based input?

If Yes - evaluate UWP first.

If No - evaluate WinUI first.



Happy evaluating!



Yes:

  • The above is probably an oversimplification.
  • There may be many situations where you don't go with the first suggested option above.
  • It doesn't consider personal preference. But if you already have a preference, you should probably use that. (Assuming it can do all you need).
  • I haven't considered support for different programming languages. (But you're almost certainly using C#).


This isn't intended to be a definitive guide. Without knowing your exact requirements, existing skills, and preferences, I can't say for sure. 

I just wanted to share some simple questions that others have found helpful when overwhelmed by the options available.