comments csharp, dotnet edit

In C# 8.0, a new form of “switch” was introduced. While similar, you’ll find that this new “switch expression” is more concise than it’s “switch statement” counterpart as it does not require all the various keywords (case, break, default, etc.).

Take this, albeit a contrived, example, starting with this enum of car makes in our pretend application:

public enum CarMake
{
    Chevrolet,
    Ford,
    Dodge,
    Tesla
}

With that enum, we can create a specific “car manufacturing service”. Before C# 8.0, that would have looked something like this:

public ICarService CarMakeFactory(CarMake make)
{
    switch (make)
    {
        case CarMake.Chevrolet:
            return new ChevroletService();
        case CarMake.Ford:
            return new FordService();
        case CarMake.Dodge:
            return new DodgeService();
        case CarMake.Tesla:
            return new TeslaService();
        default:
            throw new ArgumentException(message: "Invalid value for CarMake", paramName: nameof(make));    
    }
}

In C# 8.0, we can make this a little more concise, and, in my opinion, easier to read:

public ICarService CarMakeFactory(CarMake make)
{
    return make switch
    {
        CarMake.Chevrolet   => new ChevroletService(),
        CarMake.Ford        => new FordService(),
        CarMake.Dodge       => new DodgeService(),
        CarMake.Tesla       => new TeslaService(),
        _                   => throw new ArgumentException(message: "Invalid value for CarMake", paramName: nameof(make))
    };
}

This new expression has a few syntax improvements, such as:

  1. The variable comes BEFORE the switch keyword. This is a sure sign you’re looking at an expression, instead of the statement.
  2. The case and : are gone, in favor of =>, which is more intuitive.
  3. The discard variable, _, replaces the default case we’re used to seeing.
  4. Finally, the bodies are expressions themselves, instead of statements.

Let me know what you think about this new (and improved!) way of writing switch stateme…expressions in the comments!


This post, “C# 8.0 - Switch Expressions”, first appeared at https://www.codingwithcalvin.net/c-8-switch-expressions


comments meta, blogging, writing edit

A continuation of my previous blog post about “how I blog”. In this post we’ll take a look at the final four parts of my 7 8 step process, which I’ll reiterate here:

  1. Jekyll
  2. GitHub
  3. Netlify
  4. Microsoft Power Automate
  5. Azure Functions
  6. Azure CosmosDB
  7. Rebrandly
  8. BONUS!

In the last article, we got to the point of a new post getting pushed, and going live on the blog.

Once it’s there and my RSS feed gets updated - the “fun part” happens. I say, “fun” because all of this happens due to code and integrations that I’ve written specifically for this use case.

The Technology Stack

Microsoft Power Automate

The first stop on our way begins with Microsoft’s Power Automate (the product formerly known as “Flow”). If you haven’t seen this before, it’s a way to create a workflow, which begins with “something” triggering the workflow to begin. In my case, it comes via the trigger called, “When a feed item is published (RSS)”, and does exactly what it sounds like it’s going to do. You configure that trigger with an RSS feed to watch, and when the feed changes, the workflow - or flow - gets triggered.

Overall Flow Diagram

Looking at the screenshot above, which is my actual “Flow”, you can see it’s a very linear process until we get down to the blocks that represent separate social media sites, which I post to. The first step (after the RSS step at the very top) is called, “Call AzRebrandly”, which is an HTTP call into an Azure Function that I wrote, called, surprisingly, “AzRebrandly”. This step gives me an HTTP response that I push into the next step, “Initialize ShortUrl”, which produces a “short url”, using my custom branded domain, “luv2.dev”. The next two steps do a similar function, but these take the tags from my original blog post and turns them into properly formed hashtags for social media. Give those two pieces of data (short url and hashtags), I can then post the “alert” to Twitter, LinkedIn, and Facebook. Those are side-by-side because they represent, “parallel branches”, so if Twitter fails, LinkedIn and Facebook will still execute.

One caveat to this entire section is that I’m using “Premium Connectors” to do some of this stuff, which I get access to because I pay a monthly fee. If you’re looking for something similar, but free, check out “If This, Then That (IFTTT)”.

Azure Functions

I alluded to these items in the previous section, but now we’ll dive into the inner details of each one.

Call AzRebrandly

In the last section of this article, I’ll discuss a little bit more about Rebrandly, but its a link shortening/tracking website - ala, Bitly, but better 😀. Given that statement, you can probably figure out this custom integration, but the overall idea here stems from a limitation of the Rebrandly API/system.

If you tell Rebrandly to create a shortlink for a given URL, it will simply create it, even if you already have that link in your collection. This causes a problem for blogging because you (mostly) will want to reuse the same link every time you post that article - I do, anyway. So, to get around that, custom integration time!

This Azure function takes the original link as a parameter, checks a database to see if we’ve shortened that same link before, and then will either:

  1. Use the shortlink from the database
  2. Call the Rebrandly API to generate a NEW shortlink, and then store the mapping in the database

Once we’ve rolled through that scenario, we’ll hand back the short link - in my case, back to the Flow mentioned in the previous section. We’ll dig a little deeper into the database in the CosmosDB section down below.

Get Hashtags

This is a little more simple, as it doesn’t do anything with APIs or databases.

This Azure Function takes in the original list of tags from the blog post, sanitize them (to make sure they’ll post properly as hashtags), prepend a “#” to each tag, and return the collection.

I named this Azure Function very poorly as “AzCategories2Hashtags”, but in my case, I actually use tags. Luckily, I made it a little bit configurable, so I never went back and renamed it. So, you could easily use tags OR categories depending on how you like to post.

For example, this post uses “meta”, “blogging”, and “writing”, so this function would return a string, “#meta #blogging #writing”, which can then be added to the messages posted out to social media sites.

Azure CosmosDB

The “Call AzRebrandly” Azure Function mentioned above uses an Azure CosmosDB in the background to store those link mappings I mentioned. Each mapping gets stored in the database as JSON, which looks like this:

{ 
  "shortUrl": "https://luv2.dev/57l", 
  "destinationUrl": "https://www.codingwithcalvin.net/my-blogging-process-part-1/"
}

Then, as I pass in various a destination URL, I can check these mappings to see if one already exists, and return the “shortUrl” that accompanies that record.

That’s it. That’s all it’s used for, which gets me around the Rebrandly limitation of always creating new links for destination URLs (even if one already exists).

Which brings me to…

Rebrandly

Rebrandly. You probably haven’t heard of it. I hadn’t until I wanted to use something other than Bitly. And, you might be asking, “Why did you want to use something other than Bitly?”

The answer is quite simple. As I’ve mentioned, I’m using a custom short domain, “luv2.dev”, for all of the links. Bitly charges an outrageous amount to use a custom short domain on their service, and Rebrandly does not. In essence, it comes down to cost.

Dev.To

BONUS SECTION!

I cross-post my blogs onto dev.to (https://www.dev.to/calvinallen) to try and gain a little more exposure. Plus, the community over there is pretty awesome, so you should check it out. Dev.to has a feature that can connect to your RSS feed, and periodically import new posts. When it does this, it leaves them in a draft state, and you simply edit them and set “published: false” to “published: true”. Your mileage may vary here, because you may have to edit more of the post if the formatting went “wonky” on the way in. I usually don’t have this problem because my site and dev.to both use the same process for blog posts, so they generally come over without a problem.

Conclusion

If you’re looking to start a blog, I hope this sheds some light on “a way” you could approach it. I am NOT saying it is the “only way”, just “a way”.

And, if you need any help getting started, let me know. All my Azure Function code and blog site (all posts, etc.) are all on GitHub, so feel free. Power Automate doesn’t have a great way of sharing “Flows”, but I’m more than happy to provide an export of them if you’re interested, just ask.


comments meta, blogging edit

After a conversation about “how we blog” in a Slack channel I’m part of, I decided it may be best to just blog it. Nothing more meta than blogging about your blog, right?

My entire blogging process encompasses a variety of technologies:

  1. Jekyll
  2. GitHub
  3. Netlify
  4. Microsoft Power Automate (previously “Flow”)
  5. Azure Functions
  6. Azure CosmosDB
  7. Rebrandly

I’m going to split this into two posts given the length of the list above, so in this post, we’ll only be covering items 1-3.

The Technology Stack

Jekyll

It all starts with Jekyll, a static site generator written in Ruby. For the most part, its a basic Jekyll site, but I do have two custom plugins associated with it that do some “magic”. I also don’t post pages that have future dates, which allows me to stage articles and push them to the repository ahead of time (yes, they would be visible in the repo, just not live on the site - I’m okay with that).

Let’s talk about the plugins.

./_plugins/file_exists.rb

This plugin gives me a custom liquid tag I can use in my templates to see if a given file exists on disk. I use this for “cover image” on posts. The general idea being, for a given post, I can add a cover.jpg file alongside the post, and it gets used in social media cards. If the file doesn’t exist, I fall back to a generic image (my headshot), so I will always have a cover image - just maybe not a custom one for the post.

I use it, like so, in my atom.xml file:

{% assign cover_image = post.path | prepend: '/' | prepend: site.source %}
{% capture cover_image_exists %}{% cover_exists {{ cover_image }} %}{% endcapture %}

{% if post.image and cover_image_exists == "true" %}
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="{{ site.url }}{{ post.url }}{{ post.image }}" />
{% else %}
    <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="{{ site.url }}/images/social/headshot.jpg" />
{% endif %}

and like this, in the head.html file (which gets applied to every single page of the site, not just the posts themselves):

{% assign cover_image = page.path | prepend: '/' | prepend: site.source %}
{% capture cover_image_exists %}{% cover_exists {{ cover_image }} %}{% endcapture %}

{% if page.image and cover_image_exists == "true" %}
    <meta property="og:image" content="{{ site.url }}{{ page.url }}{{ page.image }}" />
{% else %}
    <meta property="og:image" content="{{ site.url }}/images/social/headshot.jpg" />
{% endif %}

./_plugins/postfiles.rb

This one is a little more involved, but the gist is this:

When I add a new post to my blog, I create a folder with a specific naming convention in a folder that designates the year:

/_posts/2020/2020-01-21-my-blogging-process/

Inside of that folder goes the post file itself, with the same name as the folder:

/_posts/2020/2020-01-21-my-blogging-process/2020-01-21-my-blogging-process.md

When I want to add a custom cover image to a specific post, that folder is where I would drop the cover.jpg, so you end up with:

/_posts/2020/2020-01-21-my-blogging-process/
- 2020-01-21-my-blogging-process.md
- cover.jpg

This plugin, postfiles.rb, handles moving that cover.jpg from the _posts staging folder to the REAL FOLDER when the site is compiled. By default, in Jekyll, that operation would not work, unfortunately. This allows me to place any screenshots related to a specific post into that same directory as the post, and not in some generic location at the root of the site, like, codingwithcalvin.net/images/, which takes more effort to maintain, in my opinion.

Now, you might say, “but creating all those folders and files is annoying”, and you’d be right. That’s why I have a rake task in the repo that asks me a couple of questions, and then creates the folder, markdown file, and then launches it in my editor (Visual Studio Code). The only “manual” step after that is dropping in a cover.jpg file, if necessary

GitHub

Every bit of my site is git-controlled on GitHub, and is completely “open source”. I have an edit link configured on each post that allows a viewer to create a quick edit and pull request on GitHub if they were to see a problem with a post and wanted to suggest the fix. Now, even though I use Jekyll, I am NOT using “GitHub Pages”, because they do not support the custom/unsupported plugins, which I have / use (mentioned in the previous section). And, because of that, we go into the hosting section with Netlify.

Netlify

Netlify offers free building and hosting, plus TLS certificates from Let’s Encrypt (AND AUTO RENEWALS!), and it all gets triggered when I push to the master branch of my sites repository (mentioned above).

Conclusion

That sums up the basic workflow I have of “adding a new post” and getting it deployed. Items 4-7 are all about getting that new post “socialized”, and we’ll discuss all of those, coming up in Part 2.


comments dotnet, xamarin, csharp edit

Curious what “debounce” means?

Check out my previous entry to the Software Developers’ Dictionary to find out!

I recently had a requirement to add a search field to my Xamarin.Forms / Prism application at work. This application has no local data, and for every search, hits an API endpoint that returns some JSON. Getting the search to work was easy, but then it hit me - uh oh - I don’t want to do that after every keystroke!

In comes the debounce…but how? I’m familiar with doing this in JavaScript, but not in C#, Xamarin, etc. Luckily for me, this was already a solved problem, and I can’t take credit for the code I’m going to post here, as I discovered it after multiple GoogleBings.

Since I’m using Prism, I had my search field’s TextChanged event bound to an ICommand in my View Model using Prism’s EventToCommandBehavior, and the actual search term bound bi-directional with SearchTerm, also in my View Model. All of this together looked something like this:

SearchPageViewModel.cs

public class SearchPageViewModel : BindableBase, INavigateAware {

    private string _searchTerm;
    public string SearchTerm {
        get => _searchTerm;
        set => SetProperty(ref _searchTerm, value);
    }

    private IList<ApiResult> _results;
    public IList<ApiResult> Results {
        get => _results;
        set => SetProperty(ref _results, value);
    }

    private IApiService _apiService;
    public ICommand SearchCommand { get; }

    public SearchPageViewModel(IApiService apiService){
        _apiService = apiService;

        SearchCommand = new DelegateCommand(Search);
    }

    private void Search(){
        Results = _apiService.Search(SearchTerm);
    }
}

SearchPage.xaml

(more xaml)
...
<Entry Text="{Binding SearchTerm}">
    <Entry.Behaviors>
        <b:EventToCommandBehavior EventName="TextChanged" Command="{Binding SearchCommand}" />
    </Entry.Behaviors>
</Entry>
...
(more xaml)

Those two items combined formed a functioning search box, but it lagged everytime you typed a single character until the service call returned results. Now, let’s add a 500 millisecond debounce to it!

SearchPageViewModel.cs

public class SearchPageViewModel : BindableBase, INavigateAware {

    private string _searchTerm;
    public string SearchTerm {
        get => _searchTerm;
        set => SetProperty(ref _searchTerm, value);
    }

    private IList<ApiResult> _results;
    public IList<ApiResult> Results {
        get => _results;
        set => SetProperty(ref _results, value);
    }

    private IApiService _apiService;
    
    public ICommand SearchCommand { get; }

    // ADD THIS:
    private CancellationTokenSource _throttleCts = new CancellationTokenSource();

    public SearchPageViewModel(IApiService apiService){
        _apiService = apiService;

        // CHANGE THE COMMAND TO USE THE NEW DEBOUNCEDSEARCH METHOD:
        SearchCommand = new DelegateCommand(async () => await DebouncedSearch().ConfigureAwait(false));
    }

    //CHANGE METHOD SIGNATURE
    private async Task Search(){
        Results = _apiService.Search(SearchTerm);
    }
    
    //ADD THIS METHOD
    private async Task DebouncedSearch()
    {
        try
        {
            Interlocked.Exchange(ref _throttleCts, new CancellationTokenSource()).Cancel();

            //NOTE THE 500 HERE - WHICH IS THE TIME TO WAIT
            await Task.Delay(TimeSpan.FromMilliseconds(500), _throttleCts.Token)

                //NOTICE THE "ACTUAL" SEARCH METHOD HERE
                .ContinueWith(async task => await Search(),
                    CancellationToken.None,
                    TaskContinuationOptions.OnlyOnRanToCompletion,
                    TaskScheduler.FromCurrentSynchronizationContext());
        }
        catch
        {
            //Ignore any Threading errors
        }
    }
}

For completeness, the XAML didn’t change at all!

SearchPage.xaml

(more xaml)
...
<Entry Text="{Binding SearchTerm}">
    <Entry.Behaviors>
        <b:EventToCommandBehavior EventName="TextChanged" Command="{Binding SearchCommand}" />
    </Entry.Behaviors>
</Entry>
...
(more xaml)

This has been working splendidly, and I’m very happy with it. Now, as I said, I did not author this code, but uncovered it online after many failed search attempts. It is now unfortunate that I can no longer find that post.

Please, dear reader, if you do run across it out there, please let me know so I can attribute it properly. My main reason for posting it here is to hopefully elevate a working solution for other googlebingers in the future.


comments sdd, dictionary edit

In the software development world, we sometimes have a need to “debounce” an input field.

If you’re new to the industry, you may be thinking, “de-what?”, and trying to find the answer online. Unfortunately, you’ll only find “incorrect” (incorrect as it relates to software development) definitions on traditional dictionary sites. And, sometimes, we don’t even know “debounce” is what we’re trying to do in the first place!

An example requirement where you may need to understand this term:

Add a search field to the top of the page that queries the server API in real-time for results, and displays them in the grid.

Woah, after every single keystroke, you want me to make an API call?

Usually, no, that’s not what anyone wants, but it may not be clear.

What you need to do, is “debounce” the input. If you add “debouncing” to the requirement, it may start to read like this:

Add a search field to the top of the page that queries the server after the user hasn’t typed anything for 1 second, queries the server API for results, and displays them in the grid.

At its essence, “debounce” (or the act of “debouncing”) is simply to ignore performing any action until a specified time has passed AFTER the user has finished typing.

Here’s an example. Let’s say we have a pet adoption website with a “breed” search field. As a user, I come into the site and want to search for “Labrador”. Since I am certain of what I’m searching for, and can type it relatively quickly, I don’t want you to search each letter as I type them. Wait until I stop for 500 milliseconds / 1 second, etc.

If I type “L” into the search box, and you immediately go off to search for any dog breed that contains the letter “L”, you’re going to make me wait and present results that I am not interested in. Similar issue as I type “A”, then you’re off searching for any dog breed that contains the letters, “LA”, and again, may not present what I want and have me waiting. Simply wait until I type, “LAB”, and I stop. Then you can search for any dog breed that contains the letters, “LAB”, which is going to (more than likely) get me the results I want, with only one search. The time in which you wait AFTER the user stops is up for debate on your individual product / requirements, and must be balanced appropriately. Normally, 500 milliseconds to 1 second is sufficient and doesn’t result in the user waiting too long for the results.

I want you, dear reader, to know these words and the definitions for your journey - knowing how to implement a “debounce” will depend on your technology stack, but knowing what to search for when you need it? Priceless.

And, finally, one thing to note, “debounce” is not the same as “throttle”, which I’ll get into in the next SDD entry.

I hope this helps, but please reach out if you need some extra guidance (publically or privately).


comments dotnet, csharp, xamarin edit

As soon as I received my Macbook at the new job, it was go time.

I had done some research on Xamarin Forms, and decided I would bring in Prism (and utilize Unity for IOC / DI). I looked at a few different Mvvm projects - MvvmLight, FreshMvvm, Mvvm Cross, just to name a few. Be sure to check them out if Prism doesn’t suite your needs. I ultimately chose Prism for background / history, longevity, and activity of the project. To be fair, the other projects would have likely solved my problem just as well, but since I was fairly unfamiliar with all of these technologies, I simply had to choose and move on. At some point, I’d love to revisit each of them individually.

Anyway, without further ado, let’s dive in.

First, why did I have to make all these changes in the first place? In my research of Prism, there appears to have been - at some point - a Visual Studio extension that comes with Prism project templates, but I kept seeing issue after issue about the extension and its integration with Visual Studio for Mac (which I had to use on this project). Since I couldn’t rely on the templates, I had to go about it the old fashioned way - trial and error and google.

The first thing we need to do is create a new Xamarin.Forms project. There isn’t anything terribly special about this, but I took some screenshots, just in case:

Upon launching Visual Studio for Mac, let’s create a new project:

New Project

From the next dialog, let’s choose a new Xamarin Forms, “Blank Forms App” under the Multiplatform App category:

New Xamarin.Forms Project

On the next dialog, give your app a name, identifier, and choose your target platforms. For the sake of this article, we’re selecting both Android and iOS. We’re also going to use .NET Standard for our Shared library / code. Configuration

On the final dialog of the wizard, give your project and solution a name, where to save it on disk, and whether you would like a UI Test project or not (for the sake of this article, no test project). Lastly, hit that Create button. Configuration, Page 2

After the project has finished loading, we need to add in our Prism packages. Right click on the solution node, and click Manage NuGet Packages: Manage Packages for Solution

Perform a search for prism, and select the Prism.Forms and Prism.Unity.Forms packages, and click “Add Packages”. This will bring in a number of additional packages based on the Dependencies required. Package Selection

After you click “Add Packages”, you’ll be presented with a dialog to select which projects you want to install the packages into. Select them all! Select All Projects

With the new packages installed, we can start modifying out project for Prism usage.

First, a couple folder changes: Add a new folder to the Shared code project, called Views and ViewModels: Add New Folders

With the new folders, created, let’s move MainPage.xaml into the Views folder: Move MainPage to Views

After you move the View, we’ll need to make a couple code adjustments for namespaces and such.

Open the MainPage.xaml file and modify the ContentPage declaration:

  1. Bring in the Prism.Mvvm namespace from the Prism.Forms assembly
  2. Add the prism:ViewModelLocator.AutowireViewModel="True"
  3. Finally, update the x:Class to include Views into the namespace

The file, should ultimately, look like this:

<?xml version="1.0" encoding="utf-8"?>
<ContentPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="GettingStartedWithXamarinAndPrism.Views.MainPage"
    xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
    prism:ViewModelLocator.AutowireViewModel="True"
    Title="Main Page"
    BackgroundColor="#fff">

    <StackLayout>
        <!-- Place new controls here -->
        <Label Text="Welcome to Xamarin.Forms, with Prism and Unity!" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" />
    </StackLayout>
</ContentPage>

Now, open the MainPage.xaml.cs file, and change the namespace to include the Views folder.

using System.ComponentModel;
using Xamarin.Forms;

namespace GettingStartedWithXamarinAndPrism.Views
{
    // Learn more about making custom code visible in the Xamarin.Forms previewer
    // by visiting https://aka.ms/xamarinforms-previewer
    [DesignTimeVisible(false)]
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }
    }
}

It is very possible at this point that Visual Studio for Mac might get a little wonky with the namespacing changes, and start highlighting errors. Ignore for now, and when we’re done, closing and re-opening Visual Studio for Mac should resolve those issues.

Now, we’ll add a new, empty class to act as the ViewModel for this View, named, MainPageViewModel.

Add MainPageViewModel

Open the file (if it isn’t already), and change the class to inherit from BindableBase and to implement INavigatedAware. In the end, the file should look like this:

using Prism.Mvvm;
using Prism.Navigation;

namespace GettingStartedWithXamarinAndPrism.ViewModels
{
    public class MainPageViewModel : BindableBase, INavigatedAware
    {
        public MainPageViewModel()
        {
        }

        public void OnNavigatedFrom(INavigationParameters parameters)
        {
            // Do work here when you're navigating away from this page
        }

        public void OnNavigatedTo(INavigationParameters parameters)
        {
            // Do work here when you're navigating TO this page
        }
    }
}

This is just a starting point, and other base classes and interfaces are available to use here, but you’ll have to check out the Prism documentation for that.

Let’s dig into the App.xaml and App.xaml.cs files for the final changes we need to make to the Shared project.

First, open the App.xaml file, and make two changes:

  1. Bring in the Prism namespace
  2. Change the Application node

Which should end up looking like this:

<?xml version="1.0" encoding="utf-8"?>
<prism:PrismApplication
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:prism="clr-namespace:Prism.Unity;assembly=Prism.Unity.Forms"
    x:Class="GettingStartedWithXamarinAndPrism.App">
    <Application.Resources>
    </Application.Resources>
</prism:PrismApplication>

Second, open the App.xaml.cs file to make a few changes:

  1. Change the inheritance so that App inherits from PrismApplication
  2. Implement necessary methods, OnInitialized and RegisterTypes
  3. Register your pages (for now, just navigation, but this is also where you would add additional services into the container)
  4. In the OnInitialized method, we need to call the Prism navigation service and tell it where we want to go. In this example, we’ll use the NavigationPage built into Prism and ‘Navigate through it’ to our initial starting page. This gives us a simple container around our page to use for back / forward navigation and space for the page Title.

In the end, the App.xaml.cs should look like this:

using GettingStartedWithXamarinAndPrism.Views;
using Prism;
using Prism.Ioc;
using Prism.Unity;
using Xamarin.Forms;

namespace GettingStartedWithXamarinAndPrism
{
    public partial class App : PrismApplication
    {
        public App(IPlatformInitializer platformInitializer) : base(platformInitializer)
        {
        }

        protected override async void OnInitialized()
        {
            InitializeComponent();
            await NavigationService.NavigateAsync("NavigationPage/MainPage");
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<NavigationPage>();
            containerRegistry.RegisterForNavigation<MainPage>();
        }
    }
}

That wraps up the changes we need to make in our shared project. Let’s move to our iOS project and make some changes there.

In the iOS project, open the AppDelegate.cs file and create a new class called, IOSPlatformInitializer, which implements IPlatformInitializer (remove the throw new NotImplementedException() from the method). Then, Modify the LoadApplication call in FinishedLaunching and pass in a new IOSPlatformInitializer. In the end, you should end up with a file similar to below.

using Foundation;
using Prism;
using Prism.Ioc;
using UIKit;
using Xamarin.Forms.Platform.iOS;
using Xamarin.Forms;

namespace GettingStartedWithXamarinAndPrism.iOS
{
    // The UIApplicationDelegate for the application. This class is responsible for launching the 
    // User Interface of the application, as well as listening (and optionally responding) to 
    // application events from iOS.
    [Register("AppDelegate")]
    public partial class AppDelegate : FormsApplicationDelegate
    {
        //
        // This method is invoked when the application has loaded and is ready to run. In this 
        // method you should instantiate the window, load the UI into it and then make the window
        // visible.
        //
        // You have 17 seconds to return from this method, or iOS will terminate your application.
        //
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            Forms.Init();
            LoadApplication(new App(new IOSPlatformInitializer()));

            return base.FinishedLaunching(app, options);
        }
    }

    public class IOSPlatformInitializer : IPlatformInitializer
    {
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            //register platform specific items into the IOC container here
        }
    }
}

Now we need to do (basically) the exact same thing in our Android project.

Open the MainActivity.cs file, and add an AndroidPlatformInitializer class that implements IPlatformInitializer (remove the throw new NotImplementedException), and add a new AndroidPlatformInitializer to the construction of the App in the OnCreate method. Ultimately, you should end up with something resembling the file contents below:

using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Prism;
using Prism.Ioc;
using Xamarin.Forms.Platform.Android;
using Xamarin.Forms;
using Platform = Xamarin.Essentials.Platform;

namespace GettingStartedWithXamarinAndPrism.Droid
{
    [Activity(Label = "GettingStartedWithXamarinAndPrism", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            Platform.Init(this, savedInstanceState);
            Forms.Init(this, savedInstanceState);
            LoadApplication(new App(new AndroidPlatformInitializer()));
        }
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
        {
            Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    public class AndroidPlatformInitializer : IPlatformInitializer
    {
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // Register Android specific items into the container here.
        }
    }
}

That’s it, those are all the changes necessary. At this point, you can set your Android project as the startup project and run it. With any luck, you’ll (eventually) see a screen like this:

Android Emulator

Close the Android Emulator, reset the startup project to the iOS project, and run it. Again, with luck, you’ll see a screen like this:

iOS Simulator

We’re done! Now you can begin adding views, viewmodels, navigation, etc. I’ll do a separate post on the Navigation stuff, but this should get you started!

If you’re interested in just grabbing all the code for this, I’ve got the project pushed up to GitHub - feel free to fork, copy, clone, whatever.

Enjoy, friends!


comments vscode, macos, commandline edit

As part of my new job, I had to get (and learn!) a new Macbook.

Luckily, most of the applications I need are cross-platform these days, including Visual Studio Code (my favorite all around text editor). In fact, I’m using it right now to write this post.

I installed Visual Studio Code, as per usual (following the instructions on the website). I tried to launch it from the terminal, just like I do all the time on my Windows-based machines, but it wouldn’t work! VSCode wouldn’t launch and I received an error that the command wasn’t understood. But why not, I thought to myself? It’s been installed, machine has been restarted (as a result of other installations / configurations), why couldn’t it find it?

I do what every developer does, I open up a browser and hit my favorite search engine - BING, and FINALLY, uncovered it…

Installing Visual Studio Code on a Mac, by default, does NOT add the installation directory to the PATH. Great, so what’s the answer, you ask?

  1. Launch VSCode
  2. Open the Command Palette (View | Command Palette or CMD + SHIFT + P)
  3. Type shell command, which should bring you to Shell Command: Install 'code' command in PATH
  4. Hit enter, and you’re done.

Restart any open terminal windows to pick up the PATH change, and you can use code directly from the terminal now!

Enjoy!


comments csharp, dotnet, csadvent edit

This post is part of the 2019 C# Advent Calendar.

Check it out here, for other AWESOME posts.


Did you know that planning is already underway for the ninth version of the C# language?

Now, to be fair, this has been in the planning phases long, LONG, before C# 8 shipped to us back in September 2019, as you can see from some of the discussion on the issues themselves. Most folks don’t follow the day-to-day planning of the language itself (myself included), but it’s interesting to peer into the discussions every now and then.

And, since this is Christmas Day, let’s peek in on five (there are a LOT more!) C# 9 language “gifts” we might receive sometime in 2020 (subject to change, of course!)

1. Simplified Parameter NULL Validation Code

The short version is that by decorating the value of a parameter to a method with a small annotation, we simplify the internal logic by not needing null validation / guard clauses, thus reducing boilerplate validation code. For example:

// Before
void Insert(string s) {
 if (s is null) {
   throw new ArgumentNullException(nameof(s));
 }
 ...
}

// After
void Insert(string s!) {
  ...
}

2. Switch expression as a statement expression

This one is still in the discussion phase, but the general idea is to allow a switch expression as an expression statement. For example:

private void M(bool c, ref int x, ref string s)
{
  c switch { true => x = 1, false => s = null };
}

or

private void M(bool c, ref int x, ref string s)
  => c switch { true => x = 1, false => s = null };

3. Primary Constructors

This one means to simplify all those boilerplate constructors, fields, property getters/setters, etc., that we’re so used to. For example:

// From This:
class Person
{
    private string _firstName;

    public Person(string firstName)
    {
        _firstName = firstName;
    }

    public string FirstName
    {
        get => _firstName;
        set {
          if (value == null) {
              throw new NullArgumentException(nameof(FirstName)); 
          }
          _firstName = value;
        }
    }
}

//To This:
class Person(string firstName)
{
    public string FirstName
    {
        get => firstName;
        set {
          if (value == null){
            throw new NullArgumentException(nameof(FirstName));
          }
          firstName = value;
        }
    }
}

4. Record

Slightly similar in nature to Primary Constructions (mentioned above), the goal of this proposal is to remove the necessity of writing so much boilerplate code when creating a new class / struct. It seems possible that if Record types make it in, that Primary Constructors will not (opinion). For example:

//From Something Like This:
public class Person
{
  public string Name { get; }
  public DateTime DateOfBirth { get; }

  public Person(string Name, DateTime DateOfBirth)
  {
    this.Name = Name;
    this.DateOfBirth = DateOfBirth;
  }
}

//To Something Like This
public class Person(string Name, DateTime DateOfBirth);

5. Discriminated Unions / enum class

This one took a smidge to wrap my brain around. It uses keywords that we’re all used to (plus a new one), combines them together, and adds Record’s (mentioned above) into the mix. It is, in my own words, a “cleaner” way of creating abstract base classes, and concrete types that inherit from them. For example:

// From Something Like This:
public partial abstract class Shape { }

public class Rectangle : Shape {

  public float Width { get; }
  public float Length { get; }

  public Rectangle(float Width, float Length){
    this.Width = Width;
    this.Length = Length;
  }
}

public class Circle : Shape {

  public float Radius { get; }

  public Circle(float Radius)
  {
    this.Radius = Radius;
  }
}

// To Something Like This:
enum class Shape
{
  Rectangle(float Width, float Length);
  Circle(float Radius);
}

These five proposals only skim the surface of the discussions going on around C# 9. Head over to the GitHub project, take a look, and even get involved! It’s a new Microsoft, and our opinions are welcome!

Since I’m the final post of the year, I’d like to offer a major thank you to everyone that volunteered, wrote, tweeted, retweeted, liked, hearted, shared, read, etc., to this amazing event.

This community…OUR community, is comprised of amazing folks, and I consider myself grateful to even be considered a part of it.

Whatever holiday you celebrate this time of year, I hope it’s wonderful.

See you next year, friends.


Final Note

A big thank you goes out to Matthew D. Groves for bringing this amazing tradition to life (now in its third year)!

I consider myself lucky to call Matthew a friend, and our community is a better place because of him.

Make sure and follow Matt on Twitter, and watch his live streams on Twitch. You won’t be disappointed.

Merry Christmas, Matt.


comments dotnet, mvp, csharp edit

On November 1, 2019, I received an email stating that I had been awarded Microsoft MVP in Developer Technologies for my community contributions.

I was actually in a conference call with some work folks when I received the email, and I may have - MAY - have got a little excited and interjected that I had received it. Okay, not “may”, definitely “did”.

I was nominated back in June (or July?) of 2019, so I knew I was “in the system”. I regularly had to go and log contributions into the website for things that I had done. And, that’s when it hit me. I hadn’t just got nominated for current contributions. You see, I had to log, approximately, the last year’s worth. I realized while doing that, that I had been doing some of those things for a while. And, while I most likely said to myself at some point, “let’s go for MVP”, I had been working towards it for quite some time without necessarily realizing it.

Why is that?

Because I was doing what I loved doing. It just so happens that a lot of what I love doing, overlaps into MVP territory.

You see, I had started submitting PRs against documentation to various repositories (though, honestly, mostly Microsoft docs because thats usually where I spend most of my time). I started open sourcing my own creations (you can find them on my github profile). Some of those creations were developed on my live stream (which I also started during that time frame). Of course, one of the unfortunate things about streaming on Twitch is that the videos will “disappear” after a short time period, so I also ending up starting a YouTube channel where I push all of the recordingsI made conscious decisions to volunteer in the community, because, well, I love the community. Then, I started a podcast - because one has to these days, but also because I think its fun (we just released our 11th episode!).

What I’m saying is, I was going for MVP and didn’t even realize it until much later because I was making the contributions to help others and have fun. I hope that’s why you’ll get it, too.

If you have questions, please feel free to reach out - comment here, twitter, email, etc., whatever works best for you.


comments gitkraken, powershell edit

It’s no surprise how much I love GitKraken (the single best Git GUI in existence), right?

At the same time, I still love the command-line (my preferred console at this point being PowerShell Core).

I kept finding myself at the command-line, doing something in my local repository, and wanting to launch GitKraken without touching the mouse.

Since I’m on Windows, and the GitKraken installer adds a right-click context menu option, when right-clicking in a folder, of, “Open with GitKraken”: right-click context menu option

I knew the command-line parameters to do it existed - I just needed to find them. Launch regedit and do a search for gitkraken, revealed the command I was looking for inside of:

HKEY_CLASSES_ROOT\Directory\Background\shell\GitKraken\command

All I needed to do now was port that to a PowerShell alias of gitkraken (of course, you could change the alias however you see fit - gk, etc.).

Here is the code I ended up with, added to my PowerShell Profile. Notice that I wrapped the GitKraken command in a Function, and then aliased that as I had trouble just trying to tie the GitKraken command into the alias directly (probably just my lack of PowerShell skills)

Function Launch-GitKraken {
  Start-Process -FilePath "$home\AppData\Local\gitkraken\update.exe" -ArgumentList "--processStart=gitkraken.exe","--process-start-args=`"-p `"$(Get-Location)`"`""
}

Set-Alias -Name "gitkraken" -Value Launch-GitKraken -Force

Adding the code block above into your PowerShell profile - (traditional OR core - both have been tested and work).

Also, if you use VSCode, and have your terminal set to PowerShell, you can also launch it from there, since that also picks up your profile configuration - and here is an animated gif of that in action: (inception!)

POSH Kraken in Action

If you want to give GitKraken a try, do me a favor and sign up for trial using my referral code :)