Wednesday, December 04, 2019

Uno talk notes (links)

Today I gave a talk about Uno in London.


Here are the links I mentioned (all in one handy place 😀)

Main website - https://platform.uno/
GitHub - https://github.com/unoplatform

All the latest details - https://platform.uno/announcing-uno-platform-2-0/

Try it out (Sample apps)
Android app - https://play.google.com/store/apps/details?id=com.nventive.uno.ui.demo
iOS app - https://itunes.apple.com/app/uno-gallery/id1380984680
Windows app - https://www.microsoft.com/store/apps/9NTT97F69ZHZ
In browser - https://playground.platform.uno/

Other browser-based demos
In browser DB - https://sqliteefcore-wasm.platform.uno/
SkiaSharp - https://skiasharp-wasm.platform.uno/
Community Toolkit - http://windowstoolkit-wasm.platform.uno/
Lottie (animations) - https://lottie.platform.uno/


Ask for help - https://gitter.im/uno-platform



Buy me a coffeeBuy me a coffee

Tuesday, December 03, 2019

Rapid XAML in the future

This
Rapid-XAML-Toolkit forked from the Microsoft organization
Before
has become this
Rapid-XAML-Toolkit repo now in my org
After

Yes, ownership of the repository has transferred to me.

Background

A little under two years ago, I was thinking about how more can be done to help developers building software. I was contributing to Windows Template Studio, which is a great way to get started in creating an app but wondered what could be done after that. I saw that there was a big gap in the tooling for developers working with XAML, and I had several ideas about ways this could be improved.

Skip forward a couple of months, and I had a proof of concept that I showed to some people in Redmond.
I received a positive response.
They asked what I wanted to do with it, and the conclusion we came to was to make it an "official" Microsoft open source project. And so, open-sourcing processes were followed (Yes, Microsoft has such things), a repository was created, and I began working away in my "free" time.

Fast forward to earlier this year.

I reached the point where it became realistic, practical, and necessary to start getting the functionality out to people who could use it.
In a case of bad timing, the primary advocate for the project within Microsoft left for another job.
The person who took over responsibility for the project within Microsoft then faced several months of me asking them questions. Questions like:

  • When can we get this in the marketplace?
  • What do you need from me to help this progress?
  • What progress is happening?
  • What can I do to help this progress?
  • Etc...

To try and encourage things along and provide a way for people to see what I'd been working on, I released a preview via my own publishing account.
I did a small amount of extra work in response to feedback from the preview, but the uncertainty of the project meant progress on the project slowed.

Eventually, I got an answer. This wasn't going to be something Microsoft would publish.

Not totally dejected (or surprised--given how long things had taken), I asked about my continuing the project away from Microsoft. Primarily, this meant transferring the ownership of the repository to me. As there were only minor contributions from other people and I had no plans on changing the licensing, this was agreed to, in principle, subject to approval from legal.

Cue several months of me repeatedly asking, first, "Have you asked legal yet?" and then "Have you heard from legal? Can you follow up with them?"

Until.

Yesterday I received an email that the legal department had no objections and so I made the transfer.


I've definitely learned a lot from this process.


What's next?


  • Time for me to get to work.
    While work had stalled concerning development, I've been keeping track of more and more ideas for what could be done to help developers and features to be added to the product. More details to follow...

  • Get a "proper" version released.
    I'm also going to revisit how it's packaged, so developers need only install the bits they want.

  • It will remain free and open source! An original goal was to gain experience in managing such a project, and that's still possible. While the direct Microsoft association would undoubtedly have helped, I still believe this can be a valuable tool for developers working with XAML. While Microsft continues to focus their effort on improving tooling within the visual designer, that leaves a lot of opportunities to offer tools to help within the editor.
    And, free because of not being a name that can sell the tool, I'd instead gain experience and knowledge from having a lot of people use it rather than make a small amount of money from a few users. Having spent the last 7-8 years doing work under NDA, it's getting harder to find work without any portfolio. Hopefully, this will start to show what I'm technically capable of and my knowledge of what developers want and need. This may aid in securing future consulting/contract work. I'm also hopeful the lessons and experience here may allow me to create other, paid, tools in the future.
    In a moment of what's hopefully excellent timing, I've also been approved for the GitHub sponsors program, so you can financially support this project too.

  • A new website - probably.

  • Merch/SWAG - eventually?

exciting times!




Buy me a coffeeBuy me a coffee

Thursday, November 28, 2019

How not to build code when only docs are changed (AppVeyor)

Having documentation and code in separate repositories makes sense for many projects but not for all.

When you make changes to code you want the CI process to build the code to make sure everything is ok with it. Then, once someone (or rather something) other than you have verified it's ok, it can be merged/committed.

That's all good but sometimes it can be very time-consuming.

When making a small change you can easily get frustrated if you haven't changed anything related to code.
I only fixed a typo on the readme. Why is it doing a full build?
In scenarios like this, you shouldn't be building all the code.

There are lots of reasons not to build the code but the most important is that it prevents quick, simple things from being quick and simple. The consequence of this is that if something should be quick and simple isn't people are less likely to do it (again).

I'm less likely to submit a fix for an issue in your docs if it takes hours. And yes, I count the time all the actions on the PR will take.

Fortunately, it's really simple to avoid this issue. Just configure your server to not build the code when only docs have been changed.

For my projects (built on AppVeyor) I use the following configuration to avoid building code when the only things that have changed are images (kept in the 'art directory'), anything related to docs, and/or any markdown files.

Here's the relevant snippet from my `appveyor.yml` file.

skip_commits:
  files:
    - art/*
    - docs/*
    - '**/*.md'


I'm sure there's a similar way to do this with whatever build system/server/CI/CD process you use too.

None of those things are related to the code and so there's no need to rebuild the code to look for any accidental breaking changes or failing tests.

Log entry showing build being skipped because of the file types changed


The next thing I'd like to do with my current process is to add additional checks for documentation and validate those checks only when the affected docs are changed. But that's a task for another day...



Buy me a coffeeBuy me a coffee

Wednesday, November 27, 2019

Why web wrappers are a great start for Windows 10 desktop apps

As a subject that comes up regularly, I thought I'd post about this.


Remember, not all apps are the same.
They're not all created by people with the same knowledge or skills.
They're not all created with the same goals in mind.

Having a "web wrapper" (an app that is little--if anything--more than a WebView pointing to a website) can be a great option if:

  1. If all you want from the app is a way to put the same content as the website in an enclosed desktop experience.
  2. If it's a sensible business decision based on desired goals and available resources.
  3. If the decision was not made purely based on technical abilities or developer preference.
  4. If it's that or nothing.
  5. If the experience of the packaged web content is appropriately tested.
  6. If it takes advantage of running in that environment and adjusts web-based behaviors that don't make sense when running as an app.
  7. If an installable PWA wouldn't be better.
  8. If not doing it just to be able to say, "we have an app."


Buy me a coffeeBuy me a coffee

Tuesday, November 26, 2019

Recommended Reading: non-code related books for people creating software.

Books are great. Of course, you should read mine.
When you've read that, I recommend the following books to all software developers, even though they're not about code.

Badass: Making Users Awesome – Kathy Sierra (O’Reilly, 2015)

This is a great book about how to focus on what will make your product (app) invaluable to the people who use it. The focus isn’t on apps, but you can easily apply the lessons of this book to apps and games to help make them better. Read this book if you want to create something people will love.
[amazon]

Design for Hackers: Reverse Engineering Beauty – David Kadavy (John Wiley & Sons, 2011)

This is a great book full of useful, practical instructions for creating beautiful, well-designed interfaces. The focus of the book is primarily for web design and development, but it highlights fundamental principles that developers can easily apply to the UI of apps. Read this book if you’re not a designer, but would like to improve your design skills.
[amazon]

Elements of User Experience: User-Centered Design for the Web – Jesse James Garrett (New Riders, 2002)

This book provides an accessible introduction to the world of user experience (UX). Like many of the other books listed here, it focuses on web development but also shows how to apply what it teaches to other areas too. The book provides an overview to UX and has a structure for explaining its key components (elements). Read it if you want to learn more about the formal discipline of UX.
[amazon]

Rocket Surgery Made Easy: The Do-It-Yourself Guide to Finding and Fixing Usability Problems – Steve Krug (New Riders, 2009)

This is the follow-up to Steve’s earlier book, Don’t Make Me Think! The earlier book was an introduction to the importance of usability in websites; this book explains how you can run usability tests yourself. This is another book written for people developing for the web, but it’s also widely applicable to mobile app development. Read this book to learn how to begin performing your own usability testing.
[amazon]

The Design of Everyday Things – Donald A. Norman (MIT Press, 1988)

This book is a classic introduction to design. It’s about more than just how things look and work, as it also considers the importance of understanding how they affect the people who use them and the businesses that create them. Read this to learn more about the principles of design and how they affect everything you use and create.
[amazon]


Buy me a coffeeBuy me a coffee

Monday, November 25, 2019

Should I change my presentation style to be more like other people?

Me on stage at UnoConf 2019

I've spent a lot of time researching how to be a better presenter. The result of all of that is that I've reduced my own internal guidelines to this: don't do the bad things I see other presenters doing.

I don't like it when people read a script - So, I don't use one. (Although I do write several versions of one while preparing.)

I don't like it when people are giving a talk prepared by someone else - So I make mine my own. No-one else would give the presentation in the same way.

I don't like it when people are repeating something they've heard or researched but don't have personal experiences to share - So I only talk about things I know really well.

I don't like presentations that are given multiple times in the same way - So mine are always unique. By this, I mean, they're regularly updated and adjusted for the specific audience.

I don't like it when there's no audience interaction - So I involve the audience.

I don't like it when presenters are unprepared and underrehearsed, so they can't adjust to changes or things going wrong - So I rehearse lots.

I don't like it when people are talking about things they have no passion for--or at least don't appear to care about - So I only talk about things I can get excited about.

I don't like it when presenters take ages covering a single point - So I try and include lots of things. As a downside, this means I have a tendency to rush and may not cover items in as much detail.

I don't like it when there's no benefit to seeing a presentation live and watching a video recording would have been better. - So I encourage questions from the audience.


I know my "style" is not to everyone's taste but it feels right for me.
However, maybe I'd be more effective if I was more like other presenters...


What do you do when presenting? Or think I should do?




Buy me a coffeeBuy me a coffee

Friday, November 22, 2019

SimpleTesting - Get started with coded tests in .NET

tldr: I made a thing. Get the NuGet package and read more on GitHub

I have a theory: Getting started with writing coded tests is harder than it needs to be.

I wanted to make it easier to get started by getting the number of things that need to be installed or learned before it's possible to start writing tests.

The value of writing tests is better appreciated once some have actually been written, so I've made a way to put off the things you can think about later:

  • Which test framework to use
  • Which Test runners
  • What Mocking frameworks
  • What Isolation frameworks
  • What are Mocks/Stubs/Fakes and when/how should they be used
  • How to mark up tests and test classes
  • How to indicate success or failure
  • What counts as a "unit" test
  • How many, and what, different things need to be installed.


That's a lot of things to learn or be a distraction when the aim is to write tests.

My solution requires:

  • Only installing a single NuGet package.
  • No special markup needed (attributes, naming conventions, etc.)
  • Forces tests to be clear about whether they pass or fail.


To use it:

  • Have a class that inherits from `SimpleTesting.IContainSimpleTests`.
  • Have a parameterless constructor. (One is created by default if you don't add a constructor.)
  • Create public methods that return `bool` (or `Task<bool>`)
Those public methods are then "automagically" turned into tests when the code is compiled.



And it generates tests (in a different namespace to the original class) that Test Explorer picks up and can be run from within Visual Studio.

Examples of generated tests inside Test Explorer


It doesn't do everything that a full test framework does but you can use one in combination with these "simple tests."


I'd love to hear your thoughts on this?

Buy me a coffeeBuy me a coffee

Thursday, November 21, 2019

Make the repository public - no-one cares about your code

Just make the repository public (assuming it contains no Publicly Identifiable Information or embedded secrets.)
If it does, you should remove them anyway.

The 'make repository public' setting in GitHub

There are common fears about making code public.

  • What if someone takes it and makes something with it that they start selling or otherwise competing with my project?
  • What if someone laughs at it?
  • What if someone copies something?


So what? No-one is paying attention to what you put on-line. (If they were I doubt you'd have nothing better to do than read my blog.)

  • Use an appropriate license to address possible competition concerns.
  • Ignore the haters.
  • Assume that something will be copied.


I've heard it said many times (sorry, I can't attribute the original source) that "any code on the internet will eventually end up in production."

And if it does, that's ok. I don't feel responsible for someone else's codebase if they copy something I wrote (possibly many years) previously and use it differently without understanding the nuances and possible consequences.

Searching GitHub is now my default for working out how to use an undocumented API.

By searching for uses of the method/class/whatever, I can see how/if someone else has made it work. Not in a contrived example. But, in a real (hopefully) production code-base. If they hadn't made their code public I would have been stuck. I see making as much code as possible public as a way of paying it forward to other developers.

Seeing that an API has been used successfully by someone else (and how) is incredibly valuable and has helped unblock me from many coding challenges in the last year.
If I can make my code public and potentially help others in the future, then I'm all for it. I'm sure that the only reason someone else will look at my code is if they find it as the result of a search.



While I was sitting on the draft version of this post, I received this message.
"You can't just create a blank repo and leave me hanging!"
"Oh, no!" I thought. "This contradicts what I wrote in that (this) blog post."
I'm not sure it does, though.
This was a question about a name. The name of a repository.
(I find creating empty repositories for possible future projects cheaper than buying a domain and never doing anything with it.)

The name of the repository sparked interest, and they wanted to know more of what I intended for something with that name. (Hopefully, this suggests it's a good name.)

However, with more than 100 public repositories in my GitHub account, I can't recall ever having a random email asking about any of the code they contain.

I think my point still stands.


Buy me a coffeeBuy me a coffee

Wednesday, November 20, 2019

Where's the financial value in the code I write?

tldr: this is very self-reflective and likely has no value to you. I won't be offended if you don't read further.


I don't get it.
Why are software developers paid so much? Especially when so much software is so bad?
How/Why have people paid me to write code in the past?
How can I get someone to do so again?
Especially when I write so much code for free at the moment?

💰❓

I've been thinking about money and getting paid for writing code.
This isn't meant as a dig at anyone. I'm just thinking about myself.
In part, this is because I don't have a job (or any paid work at the moment.)
Another part of this is that I haven't earned any money in the last six months.
And the final part is that I know I can't keep not earning money forever.

It might seem obvious that I should just get a job.
However, due to my family situation, I can only work remotely and part-time.

I also don't know what I want to do.
Some of the things I've worked on in the past aren't as appealing anymore. Or things that people are as interested in.

The idea of "writing code to earn money" VS "earning money to write code" has been playing on my mind. Ideally, I'd like to be in a place where I can write the code I want and still earn money. Having spoken with other people, that I've been in this position before is an exception and I may need to acknowledge this past privilege and be more realistic in the future.

I'm not sure:
- Does what I do provide value? To whom?
- What (and how much) value does what I'm capable of doing provide?
- How do you put a price on something?
- Who sets market rates? What are they based on?
- What do I want to do?

I still have some time before I have to be earning some money but I'd rather not get to the point where I'm only earning enough to get by each month.

If you've got this far and happen to have something I might be well suited to and you'd be willing to pay for, please get in touch.


Buy me a coffeeBuy me a coffee

Tuesday, October 29, 2019

Microsoft want to know if Rapid XAML Toolkit functionality is useful


The Rapid XAML Toolkit is a developer tool I've been working on but haven't been very good (yet) at promoting.

It does a few things, including providing the ability to generate XAML for a [view]model and provide additional issue detection with code fixes, the way Roslyn Code Analysis does with C# (& VB.Net).

Anyway, as they do from time to time, Microsoft is currently carrying out a developer survey relating to Data Binding to data in Windows Desktop Applications.

There's a very interesting option for an answer to one of the questions (image below)

Which, if any, of these items would help with application development? [ ] Generation of XAML templates from data model with bindings to properties

That's one of the things that you can already do with the Rapid XAML Toolkit!
And the Rapid XAML Toolkit is hosted in a Microsoft owned repository!

Clearly, RXT needs better promotion within the Visual Studio tooling team. I'll get on that, and you can help too.


If you develop Desktop apps, build with XAML, or otherwise work with databases on Windows, please fill out the survey, and be sure to select the option above.


Buy me a coffeeBuy me a coffee

Friday, October 25, 2019

How testing helps - a real world example

I've been thinking about software testing recently and found the number of real-world examples of how it's been used to be lacking. So, here's an example with real numbers to show the difference that having tests makes.

I have a project (Rapid XAML Toolkit) that does some complicated things. I've often said that I couldn't have built the functionality that's there without having tests for it. To back that up, I want to share some stats and show how having tests has helped over time.

The functionality in question uses Roslyn Code Analysis to look at C# and VB.Net code and generates XAML based on it.

The current functionality only generates XAML based on properties and ignores methods. To meet a new requirement, the tool now needs the ability to be able to generate XAML for some methods too. Testing to the rescue.

Background

The current functionality might seem quite simple, look at the code file, find the properties, and generate some XAML. At that level, it is, but there are some configurable options for what is generated that add complexity, and there are probably more ways to write properties in code than you may at first consider.

It's not the most complicated thing in the world, but it's definitely more complicated than something I can keep entirely in my head and not a group of scenarios I'd want to manage or have to repeatedly test by myself.

I've known business logic much more complicated.

Before making this new change, there were 744 tests on the code.
I created these tests when writing the original functionality. The value of these tests is that they document what the correct behavior of the code should be. These were mostly created before the feature was fully implemented, and it provided a way of knowing when the code correctly did everything it should when all the tests passed.

How these tests helped in the past

These tests contain many examples of input for different scenarios and the output they are supposed to produce when everything works correctly.

If I didn't have executable [unit] tests, I could have created documents that explained how to test everything manually, but the documentation requirement would have come with its own management overhead. Running the tests would have been time-consuming and error-prone because, well, I'm human.

In addition to the tests mentioned above, I also have a separate test process that crawls all the code files on my machine and ensures they can be processed without any unexpected scenarios being encountered that could cause the code to fail.
This has found a couple of instances where code was structured in a way I'd never encountered before. These examples became test cases, and then I changed the code to fix them. This was done in the knowledge that I could tell if my changes made to cover the new scenario changed any existing functionality because the current tests would start failing.

There have been a couple of times where other people have found scenarios I'd not considered and were not covered by the code. You might know these as bugs. How did I fix them quickly? Well, by adding new tests to document the correct behavior for the new input scenario, then changing the code to make the latest (and all existing) tests pass.

Adding new functionality

Getting back to the new functionality I need to add.
The requirements are:
  1. Add the ability to generate XAML for some methods in C# code.
  2. Add the ability to generate XAML for some methods in VB.Net code.
  3. Don't break any of the existing functionality.
Having the existing test suite makes point 3 really easy and quick to verify. If any existing tests start failing, I know I've broken something. They only take a few seconds to run, and I don't have to worry about making any mistakes when running the tests.

The first thing I encountered was that there were four existing tests related to the new functionality. These dictated what should previously be done when a method that will now be treated differently is encountered. As this functionality is changing, these tests no longer served any use and so were deleted. I'm always very cautious about deleting tests, but as these would be replaced with new tests that defined the new desired functionality, so that's ok.

I was able to define all the requirements for the C# version of the new functionality by creating tests for each of the new requirements.
This meant 14 more tests were added.
I then changed the code to add the required functionality.
Once all the new tests were added and passing (which took a few days worth of work), I knew all the new functionality worked correctly.

Adding the VB version was even easier.
I took a copy of the new C# tests and converted them to VB.
With a complete set of VB tests and a reference implementation in C#, implementing the VB functionality, verifying it was correct, and all other functionality still worked in the same way (i.e. I hadn't accidentally broken anything) took less time than writing this blog post!



I now have 767 tests that document all the current, correct behavior.
Not only have these saved me development time while adding features by avoiding the need for me to repeatedly manually verify that everything created previously hasn't been accidentally changed.
But they also have value for the future.

The Future

The next time I need to add a feature, fix a bug, or ensure an edge-case I hadn't accounted for before is handled correctly, I can make sure that I don't break (or change) any existing functionality in just a few seconds.

If I didn't have tests, any future changes would require that I manually verify that all existing functionality still all worked the same way. The reality of performing such tests myself is that the following would happen.

  • It would take ages. (I estimate a couple of days--at least.)
  • I'm not confident I wouldn't make mistakes and so not test everything accurately.
  • I'd get bored. Which would diminish my enthusiasm for the project, future changes, and responding to support issues.
  • I'd be tempted to skip some tests. This could lead to changes in functionality, accidentally getting into the software.

It's not that I'm too lazy to test manually; I just value my time and the quality of the software too much to not create automated tests.

Buy me a coffeeBuy me a coffee

Tuesday, October 22, 2019

Deserializing generic interfaces with System.Text.Json

.Net Core 3.0 introduces new JSON (de)serialization classes in the System.Text.Json Namespace.

These are high-performance classes for working with JSON. If you really don't want to use JSON.Net or need to get the most from your serialization performance you may want to consider them.

As they're new, documentation isn't a thorough as other JSON solutions and some things work a bit differently.

One thing that's particularly non-obvious is how to deserialize to a generic interface of interfaces.
e.g. an `IList<ISomething>`.

This is a problem I was recently challenged with.

It's easy to use a converter to deserialize a single interface to a concrete type with an attribute on the property.


   [JsonConverter(typeof(InterfaceConverter<FormattedDate, IFormattedDate>))]
   public IFormattedDate Opened { get; set; }


   ...

   class FormattedDate : IFormattedDate
   {
       public string DateValue { get; set; }
   }

   interface IFormattedDate
   {
       string DateValue { get; set; }
   }

   public class InterfaceConverter<M, I> : JsonConverter<I> where M : class, I
   {
        public override I Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return JsonSerializer.Deserialize<M>(ref reader, options);
        }

        public override void Write(Utf8JsonWriter writer, I value, JsonSerializerOptions options) { }
   }

However, this doesn't work with generic interfaces.

For this, we need to use a converter factory. Actually, we need two, but first, what is a converter factory?

A converter factory takes a type (class, property, etc.) and can return a converter to use to serialize (write) or deserialize (read) instances of that type.

Rather than use attributes to tell when to use the converter, the factories are passed to the serialization methods.

    var serializerOptions = new JsonSerializerOptions
    {
        Converters = {
            new InterfaceConverterFactory(typeof(FormattedDate), typeof(IFormattedDate)),
            new IListInterfaceConverterFactory(typeof(IFormattedDate)),
            }
    };

    var goodObj = JsonSerializer.Deserialize<GoodObject>(json, serializerOptions);

Above, you can see two converter factories and this is what we need for our particular problem.
During the [de]serialization of a type, the serializer will ask the factory if there is a converter for the type.

    class GoodObject
    {
        [JsonConverter(typeof(Converters.InterfaceConverter<FormattedDate, IFormattedDate>))]
        public IFormattedDate Opened { get; set; }

        public IList<IFormattedDate> ImportantEvents { get; set; }
    }

The handling of types during [de]serialization happens at the broadest level first, so to deserialize the `ImportantEvents` in the above class the serializer will look for a converter for `GoodObject`, `IList`, and `IFormattedDate` in that order, assuming that the type has not already been handled by an earlier converter. This knowledge is enough to solve the problem.

Adding a converter to deserialize an `IList<I>` into a `List<I>` is the first step.

    public class ListConverter<M> : JsonConverter<IList<M>>
    {
        public override IList<M> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return JsonSerializer.Deserialize<List<M>>(ref reader, options);
        }

        public override void Write(Utf8JsonWriter writer, IList<M> value, JsonSerializerOptions options)
        {
            throw new NotImplementedException();
        }
    }

Then we need an appropriate factory to create this converter.

    public class IListInterfaceConverterFactory : JsonConverterFactory
    {
        public IListInterfaceConverterFactory(Type interfaceType)
        {
            this.InterfaceType = interfaceType;
        }

        public Type InterfaceType { get; }

        public override bool CanConvert(Type typeToConvert)
        {
            if (typeToConvert.Equals(typeof(IList<>).MakeGenericType(this.InterfaceType))
             && typeToConvert.GenericTypeArguments[0].Equals(this.InterfaceType))
            {
                return true;
            }

            return false;
        }

        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
        {
            return (JsonConverter)Activator.CreateInstance(
                typeof(ListConverter<>).MakeGenericType(this.InterfaceType));
        }
    }

Because this will return a concrete list of interfaces and the serializer doesn't know how to handle those interfaces, it will ask the registered factories if they can provide a converter. We can use the converter we originally used in an attribute, we just need to add a factory to create it.

    public class InterfaceConverterFactory : JsonConverterFactory
    {
        public InterfaceConverterFactory(Type concrete, Type interfaceType)
        {
            this.ConcreteType = concrete;
            this.InterfaceType = interfaceType;
        }

        public Type ConcreteType { get; }
        public Type InterfaceType { get; }

        public override bool CanConvert(Type typeToConvert)
        {
            return typeToConvert == this.InterfaceType;
        }

        public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options)
        {
            var converterType = typeof(InterfaceConverter<,>).MakeGenericType(this.ConcreteType, this.InterfaceType);

            return (JsonConverter)Activator.CreateInstance(converterType);
        }
    }

Now we can deserialize a provided string.

    var json = "{\"Opened\":{\"DateValue\":\"2019-10-21T13:35\"}, \"ImportantEvents\":[{\"DateValue\":\"2019-10-21T13:36\"},{\"DateValue\":\"2019-10-21T13:37\"}]}";

    var serializerOptions = new JsonSerializerOptions
    {
        Converters = {
            new InterfaceConverterFactory(typeof(FormattedDate), typeof(IFormattedDate)),
            new IListInterfaceConverterFactory(typeof(IFormattedDate)),
            }
    };

    var goodObj = JsonSerializer.Deserialize<GoodObject>(json, serializerOptions);

Yay!






Buy me a coffeeBuy me a coffee

Thursday, September 19, 2019

Rapid XAML Toolkit - Now in preview!

Oh, the joy when a side project reaches a release milestone.

The Rapid XAML Toolkit is a collection of tools (hence the name) for helping with XAML development. The idea is to help fill some of the gaps in the current, MS provided tooling.

Today I'm in Montreal at #UnoConf (actually on stage as this post goes live) talking about this project and the great news is that there's now a preview version available that you can download and try it out yourself. Get it in the Visual Studio Marketplace now.

VS Extension search results showing the Rapid XAML (Preview) entry

This is an official-unofficial preview. There will be an official (signed by Microsoft*) version shortly.

So, what does it do?

There are two main things it does: XAML Generation and XAML Analysis.

It can create a stub UI from the ViewModel based on the types, names, and accessibility of the properties. Highlight the properties, copy them (as XAML) and then paste them on the view, where you want. Or just drag the VM (from solution explorer) onto the designer.
If you write your ViewModels before the Views, this should save you some time. It won't be the final UI for your app, but it's a big step in the right direction.

Additionally, it can perform analysis on XAML in the same way that Roslyn Code Analyzers do for C# and VB. You'll see squiggly lines under issues or places for improvement like in the image below. As you'd expect, you can press ctrl+. and access suggested actions to automatically make the proposed changes.

Screenshot showing XAML analysis errors

It works with UWP, WPF, and Xamarin.Forms.

If you use XAML to build apps in Visual Studio (on Windows), I'd love if you could try it out and share your thoughts, experience, suggestions, comments, or anything else on GitHub.


Sound good?


* There's a complicated relationship with Microsoft and me regarding this project. The code is all open-source on GitHub (MIT Licensed) under the Microsoft org account. I've written most of it. They're (eventually) going to publish it. The long term situation is still under discussion.

---

Fun bonus image that also relates to something I showed in my UnoConf talk, which I'll leave open to your interpretation.

Cross-Platform Template Studio - name TBC


Buy me a coffeeBuy me a coffee

Thursday, July 18, 2019

UWP inline design-time data - helper library v1.1

Over the weekend I announced my library to enable inline design-time only data in UWP apps.

Now, I've released an update (v1.1) which allows it to work with the supported properties on any control.
This removes the limitation of only working on default classes and you can use it on any object with the relevant property. This could be your own (custom) control or one from a 3rd party library.

The source is also now available at https://github.com/mrlacey/UwpDesignTimeData

Buy me a coffeeBuy me a coffee

Sunday, July 14, 2019

UWP Inline DesignTime data

TLDR: UWP apps can now simulate the inline design-time data that Xamarin.Forms supports.
Simply install `Install-Package UwpDesignTimeData`
Then, do things like this in your XAML: `dt:DesignTime:Text="Only shown in designer."`

---

Let's say you have a simple page in an app. Imagine something like this. It's a default settings page as generated by Windows Template Studio.


Now imagine this is a localized app and so all the text comes from a resource (RESW) file.
In this situation, the XAML will contain Universal Identifiers (`x:Uid`) for each element and the text will be defined in the resource file (for each language.)
These files will look something like this:


That's great, but if you want to change what the page looks like, the designer isn't a lot of help.
Here's what the designer shows.


This is far from great and it's something I can make better based on my knowledge of attached properties and the way the XAML designer works.

Simply install my new NuGet package. UpwDesignTimeData.
Then modify the XAML like this.
The designer now looks like this.
Yay!

It's not just great for localized content, it can also provide design-time data for values set with a binding.



It doesn't only work with text. It supports the following properties:

  • Caption
  • Content
  • Date
  • Description
  • FlowDirection
  • Footer
  • Header
  • Icon
  • IsChecked
  • IsOn
  • Maximum
  • MaxRating
  • Minimum
  • OffContent
  • OnContent
  • PaneFooter
  • PaneHeader
  • PaneTitle
  • Password
  • PasswordChar
  • PlaceholderText
  • PlaceholderValue
  • QueryText
  • Source
  • Symbol
  • Text
  • Time
  • Title
  • Value

These should work with all the standard controls. It won't work with custom controls. Sorry.

It even works for a few things that you can't do in XAML with the regular properties.
For example, you can specify a date or time for the DatePicker (or TimePicker) as strings and it will try and parse the value and then show it.



It works with Visual Studio 2017 and 2019.

Things to note.
  1. You may need to (re)build the project to force the designer to refresh and show the design-time data.
  2. If you find a bug or something that it doesn't work with, please log an issue with the details.
  3. If you define the actual and design-time versions of the same property, specify the design-time version second. This is necessary because of the way the XAML designer works.
  4. This should work regardless of the version of the SDK you are targetting (or have as the minimum.) If it doesn't work in your scenarios, please log an issue with the details.
  5. Documentation will follow.
Important.
Xamarin.Forms already has native support for this functionality. Hopefully, UWP (and WPF) will get this officially at some point in the not-to-distant future. ;)
When that happens, I hope and expect you'll be able to simply remove this package from your app and replace all instances of "dt:DesignTime." with "d:".


Buy me a coffeeBuy me a coffee

Sunday, July 07, 2019

Using data from SQL Server and/or Web API in UWP apps - Feedback wanted

In the next release of Windows Template Studio (the amazing tool for scaffolding your modern Windows apps) we'll be adding options to make it easier to connect to a SQL Server database or also create your own Web API.

If you've done, or are interested in either of these things your feedback will be gratefully appreciated.

SQL Server

In many enterprise scenarios, the ability to connect to data from a SQL Server database is a must. Adding appropriate references to a project can be more work than many developers would like and so this option makes setting up the project appropriately only require a single click.
Of course, it's still necessary to retrieve and load the required data but you'd have to do that anyway. What this option does is just set up the project so that this is easy to do. It also adds appropriate TODO notes so you know where the generated code needs to be modified. Additionally, there's also a method that shows how to use data from a NorthWind sample database as a replacement for the SampleData that is used by default by the pages included in the generated app.
This is deliberately not an option for generating an app based on the contents of a database. There are other tools available if that's something you want to do.


Web API (and HTTP data access)

Taking heavy inspiration from the MobileAppService option when creating a Xamarin.Forms app, we've added the ability to include an ASP.NET CORE Web API  project in the generated solution. If you are creating a custom web-based API to go with your new app, this should make it that little bit easier.
Differences between these new options and the Xamarin.Forms version are that we take a dependency on the "App.Core" shared library to avoid duplication, return our own `SampleData` in the default controller, and we've separated the code for the app to retrieve content from the API in a separate `HttpDataService` class so that they're available in apps that don't want (or need) to include the Web API directly.


As with everything that is included in Windows Template Studio we tread a delicate balance between providing enough to avoid developers needing to do more than they must, but also not being explicit on how something must be done, or including lots of code that must be removed.

If you have thoughts on any of the above, I'd love to hear them.



As an own-trumpet-blowing aside, the addition of these options means I now personally claim responsibility for twenty (20) of the options available in the WTS wizard. I've done a load of other stuff too (VB.NET support & internal testing being the main areas) but thought this was a nice milestone to celebrate.


Buy me a coffeeBuy me a coffee

Tuesday, June 25, 2019

How much code is there? (Counting lines of code)

Lines of Code (LoC) isn't the greatest of metrics (and definitely not a sign of productivity) but sometimes it can be interesting to know.

Last week, after giving a demonstration of the Rapid XAML Toolkit someone asked me just how much code I'd written.

I didn't have a way to quantify this so I said I didn't know. "What counts as 'quite a lot'?"

Later I was thinking about the question and it made me wonder "What even is a quick way to count LOC in Windows?"

I didn't know.

Then I remembered that it's something I used to do regularly in Linux with one command. This was probably prompted as I gave a talk about Windows Subsystem for Linux (WSL) earlier that day.

WSL makes it easy to do things on Windows that are easy on Linux.

So, to count the lines of code in a project on Windows.

  1. Open the folder, with the code in, in Windows Explorer.
  2. Open WSL there (Shift+Right click and select 'Open Linux shell here', or type 'wsl' in the address bar.)
  3. Type `find . -name '*.cs' | xargs wc -l`  (assuming you're using C#)
  4. Look at the number

Screenshot of output from the command


Wow, that's 33463 lines of code in RXT.
Much more than I would have guessed.
Ok, so it includes blank lines and lines that only include curly braces but it's still quite big.

I wonder how many lines it will be by the time we release the preview...

Buy me a coffeeBuy me a coffee

Tuesday, June 18, 2019

What’s New for the Command line and Windows Subsystem for Linux #InsiderDevTour

Today at the #InsiderDevTour in London I gave a talk about WSL and the new Terminal.

Here are some useful related links that might be useful if you want to learn more about this.




Buy me a coffeeBuy me a coffee

Monday, May 20, 2019

UWP Terminology



The Universal Windows Platform (UWP) has never been just one thing.
As a "platform" it incorporates many elements. There was the UI (which was a new "flavor" of XAML.) There were all the new platform APIs. And there was a new application isolation and packaging capability.
With a new operating system, designed to work on lots of different devices, you'd expect a lot of new functionality and capabilities.
Having a single term for all these capabilities that's different from the OS itself (which could still support old development capabilities as a way of maintaining backward compatibility) was a useful shorthand. "UWP" was that term.

UWP had some limitations as a term. That many people wanted "Universal" to mean any device or OS, not just Windows was one of them. Those people missed the second word in the term though. It meant "universal" across Windows devices. As a counterpoint, at the time Apple was using "Universal" to mean iOS apps built to run on both the iPhone and iPad.
There was also uncertainty as it was clear what made an app a UWP app. Even on Microsoft's own page explaining this, I don't think it's clear to be able to say if something is a UWP app or not.

Here's the thing though, it doesn't matter.
An app can be a UWP app regardless of the technology the UI is created with.
Any app which uses Windows 10 specific APIs can be a UWP app.
Any app can be packaged as a UWP app.

So, as the term loses its meaning, the need to use it diminishes as well.

WinUI covers everything to do with creating a modern, fluent, Windows 10 related interface.
Any app can use Windows [10] APIs.
And any app can be packaged with MSIX.

Maybe we'll need to use these terms in combination with "UWP" for a while (I've used "WinUI/UPW" to connect the two ideas in what I hope is just a transition phase) but hopefully not forever.
This isn't the "death of UWP", this is just an acknowledgment that the term isn't all that helpful and we can use other terms for more specific aspects instead. The underlying technologies aren't going away and there's no value in arguing over if an app is a UWP app or not.


Buy me a coffeeBuy me a coffee

Thursday, April 25, 2019

The one certainty I have about open source software

Photo by Hanny Naibaho on Unsplash

This is the short version of something much longer I have been thinking about.

Many things are currently being said about Open Source development, its maintenance, and how people who contribute towards it are supported.
It's a big, complicated subject with lots of strong opinions and no easy solutions.

I do, however, think there's one simple thing that anyone who uses open source software can do to help.

Say Thank You.

How do you say thank you?
Here are a few ways:

  • Send them a thank you tweet or email.
  • Leave a review or rating in the store/marketplace/repository where you got it from.
  • Donate, if/where appropriate.

Here are a few links to a few of the places you may be getting the results of the hard work of other developers.
Visual Studio extensions | VS Code extensions | Azure DevOps extensions | NuGet | Chocolatey | NPM

Help make open source developers feel happier and more appreciated by finding something you use at one of the links above and saying thank you.

You benefit too. Being grateful makes you happier. Harvard medical school say that's the case so it must be true.


Have you thanked an open source developer today?

Buy me a coffeeBuy me a coffee

Tuesday, April 23, 2019

Can I put the best parts of a user group/meetup in a podcast?

tldr: I'm going to start a new podcast that will just be developers talking about what they've developed. If you want to be on it get in touch.

----

I organized and ran user groups for the best part of ten years. Firstly, I took over DevEvening, and then I started the Windows Phone User Group which eventually became Windows Apps London.

Of these groups, one of the things I was most proud of was the ability to get regular attendees to talk about what they were working on or had built. Many group organizers will tell you that this can be very hard to do.
Having people talk about their actual experiences was also one of the most requested things whenever I asked attendees about what they wanted at future meetings.

My family circumstances changed a couple of years ago and we now live in a remote area that makes hosting in-person user groups/meetups difficult. However, recently, I've been thinking about how I can take some of the best parts of the groups I used to run and do something that would work regardless of location.

So, I'm going to try this:
I want to take the short, simple demos that were so popular at in-person events and create audio versions of them and package them like a podcast.

Yes, a visual format might be better for some things but I'll start with just audio and maybe extend to video in the future based on feedback.

It will be simple.
For many people, standing up and giving a talk can be daunting. I made it simple by asking the speaker to answer three questions:

  1. What have you built?
  2. Why did you build it?
  3. What did you learn in the process?

I'm hoping this structure will work for a podcast/audio version too, as it's simple but provides opportunities to develop in different ways as appropriate.
As with the short demos people used to give, it will be between 5 and 15 minutes long. Anyone can talk about what they've made for 5 minutes and will easily find they can say much more.

Talking for 5-15 minutes about something you are an expert in is easy. (If it's software that you developed, I consider you an expert in it.)
I'm also hoping this will avoid people being put off by not requiring a lot of preparation or being worried about "filling an hour".

If you've developed something, however big or small, other developers want to hear about it.

Expect lots of links in the show notes.

For now, I'd like to just focus it to Windows. Hey, it's what I know a bit about and having a level of targeting/focus will, hopefully, help with finding an audience and setting appropriate expectations.

If you've built something for Windows (however you define that), be it an app, a tool, a library, a service, or something else and would like an opportunity to tell people about it, then I'd love to have you on my new podcast.


Buy me a coffeeBuy me a coffee

Tuesday, January 22, 2019

Usability Matters - Deal of the Day - 50% off


My book is Manning's Deal of the Day today (Jan 22) so if you don't already have a copy, you can get one for half price. Yes, 50% off!

Simply use code dotd012219au when ordering at https://www.manning.com/dotd
Buy me a coffeeBuy me a coffee