Breaking Changes for Prism Autofac Users

History

It's certainly been no secret that I've told user's that Autofac wasn't really a good choice for Prism Forms. To be honest just looking at the benchmarks between Autofac and DryIoc or SimpleInjector which may soon be supported, Autofac just isn't that appealing to me. The truth though, is that I wasn't just steering people away from Prism Autofac for this reason alone.

Before Prism introduced .NET Standard support, we were limited to targeting Autofac 3.5. As anyone familiar with Autofac is likely aware, the ContainerBuilder.Update(Container) method was deprecated. Autofac quite annoyingly wants to be an immutable container. This is problematic for frameworks like Prism, or any developer who wants to dynamically load dependencies (more on this later). Also part of the problem was that Autofac is a bit unique in the way that it handles registering and resolving. Most containers are responsible for registering dependencies, telling you if something is registered, and resolving that dependency, but Autofac wants to be different with a ContainerBuilder that is used for registering, a central IContainer that knows nothing about itself, but is happy to resolve IComponentContext if you need to inject something into a class to resolve dependencies in a factory method like the one used by the NavigationService to resolve your Views... 

Major Breaking Changes

Prism Forms is architected for a Container that knows how to do stuff, continuing to have the Autofac PrismApplication derive from PrismApplicationBase<IContainer> was a poor choice. To help fix the way Autofac works with Prism Forms this was updated to PrismApplicationBase<ContainerBuilder>. That alone though would provide for a poor experience so this was updated to ensure that the Container property is still the IContainer that is set when the builder is built, and a Builder property was added to give you direct access to the ContainerBuilder being used in PrismApplication to register all of the Prism services. Unlike the builder previously used by PrismApplication, this builder waits to call Builder.Build() until after it registers the base Prism services, anything in your RegisterTypes() and anything in your IPlatformInitializer.

To make this work though, we also had to break all of your View Registrations. The extension methods that we typically include in Prism Forms are based on the Container for registrations. But this never made sense for Autofac, leading to extension methods that would create a builder, and then update the Container. To better align with the intent of how Autofac is meant to work the methods were updated to be based on the ContainerBuilder.

public class App : PrismApplication
{
    protected override void RegisterTypes()
    {
        Builder.RegisterType<Foo>().As<IFoo>();
        Builder.RegisterTypeForNavigation<ViewA>();
    }
}

public class iOSInitializer : IPlatformInitializer
{
    public void RegisterTypes(ContainerBuilder builder)
    {
         builder.RegisterType<SpeakImp>().As<ISpeak>();
    }
}

Modularity

Modularity hasn't been huge in the Prism Forms community like it is in the WPF community. For developers who are familiar with it, Modules are often a major part of their app development. Unfortunately Autofac's desire to be immutable poses some major problems for Modularity with Prism. Prism relies on container mutability for Modules. Part of this is that we must resolve the ModuleCatalog before we run it and initialize any of the Modules. The other part is that Prism allows us to load Modules on demand. This could for instance allow us to ship an application like Lyft and only load the Driver Module if the user is a Driver. Since Autofac is immutable this creates a major problem for us, and OnDemand Modules are out of the question due to the limitations imposed on us by the container. As such the recommended guidance for Autofac users will be to architect modules as follows:

public class AwesomeModule : IModule
{
    public void Initialize() { }

    public static void Initialize(ContainerBuilder builder)
    {
        builder.RegisterType<FooService>().As<IFooService>();
        builder.RegisterTypeForNavigation<ViewA>();
    }
}

public class App : PrismApplication
{
    protected override void RegisterTypes()
    {
        // Initialization must be done before the Container is built.
        AwesomeModule.Initialize(Builder);
    }

    protected override void ConfigureModuleCatalog()
    {
        // Not actually needed for Autofac since all registrations must be done
        // before we build the container.
    }
}

Getting Started

These changes are all available starting with Prism 7.0.0.30-ci in the Prism MyGet feed. If you have not already done so, you can add that feed in either Visual Studio or Visual Studio for Mac and update your existing Prism Application's to the latest CI build. 

If you are starting with a new Project you will want to check out the updated QuickStart Templates which now includes the only Module project template, and full support for the updated Autofac implementation.

Prism 7.0 for Xamarin Forms Sneak Peek

Prism 7.0 Sneak Peek

If you're a Xamarin developer, chances are you've been through a struggle or two with NetStandard. NetStandard offers a lot of advantages, but support has been slow going in many cases. Xamarin Forms only recently began shipping NetStandard. Prism users have been asking for a while now to have NetStandard support. Obviously for WPF users NetStandard really doesn't offer any advantages, and for UWP it just creates a few headaches, but that hasn't stopped requests for the Core to support NetStandard or for Prism Forms to be converted. For a while now I've been either pointing people to my preview templates or telling them to use the PackageTargetFallback attribute with the new csproj format. Well, I'm happy to say that Prism for Xamarin Forms is now available in NetStandard!

While NetStandard support is fantastic, I probably wouldn't take the time to write a post just about that. One of the problems we all face is when we run into an issue with a library in our code base, and the issue is fixed on GitHub. The problem is that it may be days, weeks, even months before it is available. So suddenly you have to uninstall the NuGet packages, add the open source library as a git submodule. As Prism moves into the 7.0 update, I'm also very happy to announce the official Prism MyGet feed that is tied into the builds so when new features are added you can immediately expect a new CI package available on MyGet so you can immediately start using the features you need without having to wait for an official release. 

https://www.myget.org/F/prism/api/v3/index.json

Whats New Since 6.3

You may be thinking that NetStandard is great and all but that isn't really new. As part of Prism updating to Xamarin Forms 2.3.5, you will now have full support for working with Prism on macOS applications. 

Another change you can look for starting now in the 7.0 addresses the overhauled OnPlatform starting in Xamarin Forms 2.3.4. Unfortunately the new Xamarin API for OnPlatform uses magic strings, and is cumbersome to say the least if you're working with it from C# code and not in XAML. Prism has updated the IDeviceService and provided a new RuntimePlatform enum. We have also updated Platform dependent View Registrations to use this new RuntimePlatform enum. This will ultimately be a lot cleaner than the previous type based registrations.

Container.RegisterTypeForNavigationOnPlatform<MainPage, MainPageViewModel>("Main",
     new Platform<MainPage_Android>(RuntimePlatform.Android),
     new Platform<MainPage_iOS>(RuntimePlatform.iOS));

Following the deprecation of the previous OnPlatform functions within the Xamarin Forms Device class, we have updated IDevice to deprecate this feature as well and added access both the Xamarin Forms Platform string and our RuntimePlatform enum.

I have been a huge advocate for directly binding to your model's properties. It really saves a lot of headaches with validation and ensuring that changes made on the view update your model to be persisted to your data store. That said even with Prism's DelegateCommand.ObservesProperty, this has been a shortcoming. Thanks to a community contribution this will now be possible in Prism 7.0

ObservesProperty(() => Property.NestedProperty.NestedPoperty)

Another major improvement addresses exceptions thrown during navigation. Prism Forms will now properly log and re-throw exceptions that are thrown when you're navigating. This has been a major pain point in the past where the exceptions were effectively swallowed by the NavigationService and you had no idea what threw an exception or even what the exception was. Many times you might have simply found yourself getting an exception thrown because your MainPage was null and the platform excepted something. 

There have also been a number of reported Navigation Bugs fixed in Prism 7.

Prism for UWP Developers

If you're developing UWP applications with Prism there are a couple of gotcha's that you'll need to know about. 

Starting in Prism 7.0 we've decided to split all of the Platforms/Containers into separate packages. We've done this so that we can rev the platforms separately from one another, and if we update an issue with Prism.Autofac.Wpf, Prism.Autofac.Windows user's won't see a package update and think that something changed. This only affects UWP developers who are using Prism for UWP. You simply need to uninstall the Prism.{Container} package and install the Prism.{Container}.Windows package. (note that this update is not yet available but will be soon)

Whether you're using Prism for UWP or Prism for Xamarin Forms, note that there is a bug with the .NET SDK that will affect you if Prism 7 is the first NetStandard package that you are using. It is easily overcome by adding the file Directory.Build.props next to your solution file, with the following contents:

<?xml version="1.0" encoding="utf-8"?>
<Project>
  <!-- Workaround for https://github.com/dotnet/sdk/pull/908 -->
  <Target Name="GetPackagingOutputs" />
</Project>

Note that if you are developing a UWP application with the Prism QuickStart Template for Xamarin Forms, this has already been added for you.

Whats Coming

As amazing as NetStandard is to finally have behind us, I'm still even more excited by what's coming in 7.0. I wouldn't call this an exhaustive list, but here are some highlights of some features to keep an eye out for in Prism 7:

  • Querystring navigation is one of the most amazing things about the Prism Navigation Service, and it's about time that you should be able to dynamically create tabs or use modal navigation through the querystring.
  • Removal of support for the Xamarin Forms DependencyService. This really leads to some bad practices, and with IPlatformInitializer there is simply no need to rely on the Dependency Service for Platform specific types.
  • An ability to use MVVM and the ViewModelLocator with custom Views as well as Xamarin Forms Pages.

 

Prism Quickstart Templates

Quickstart Templates for Prism Forms

So you had this great idea for an app... maybe you spent weeks planning with your team or with your client. The day finally comes to create the project. Suddenly you realize that we have this new .NET Standard thing and you want to take advantage of that too. You remember you need icons, you want a Splash Screen... all of the things that go into making an App. For anyone who has done this, you know there's a lot of heavy lifting to be done. In all honesty you could easily spend several days just getting a new project from File -> New to something that you're ready to start working on.

It was for this and so many other reasons that I realized we need better templates, and we need something that can help us whether we're on a Mac or on PC.

There are some very basic things left out of the base Xamarin & Prism Templates. For some developers these just require time that could be better spent on something else, and for other developers it leads them down a path of poor design.

Features

Why should you use these templates? Well here are a couple bullet points:

  • Gets you off the ground following Best Practices
  • *Starts you off using Prism for Xamarin Forms with either DryIoc or Unity for Dependency Injection
  • Already has all of your App Icons added so all you need to do is drop in the replacement files from File Explorer or Finder. There is also a link in there so you can see how to get all of your icons generated for you correctly in all of the sizes with all of the correct naming.
  • Starts you off with some base colors to use for your project with information of how to develop a Material Design pallet for your application.
  • By default it already has everything you need for Localizing strings in XAML
  • It's cross platform, using dotnet new you get the same experience from the command line whether on Mac or PC.
  • Item templates to generate Views and ViewModels with support for the common Xamarin Forms pages as well as PopupPages
  • Makes it easier to inject variables at Build to protect sensitive project secrets.
  • Quickstart with a fully working Todo app working with in memory data, Realm, or Azure Mobile Client
  • Included config for MFractor

*NOTE: Autofac & Ninject will be reintroduced once Prism 7 has a public preview.

Best Practices

App development can be simultaneously fun and frustrating. So many developers love Xamarin Forms because it really narrows down the number of API's you need to work with. What it doesn't do is eliminate your need to understand the platform your application will run on. These templates will not eliminate that need either, however they do set you down the right path, with some basic things like a splash screen so your user will at least see something while your app loads. Also included by default is the MVVM Helpers library from James Montemagno so that you can use his ObservableRangeCollection<T> to reduce the notifications sent to the UI when updating or replacing multiple items in your collection. If you don't use it MVVM Helpers you still get a ViewModelBase that will incorporate these properties as well as well as IDeviceService and virtual implementations of INavigationAware, IActiveAware, and IApplicationLifecycle.

Prism

Continuing really with Best Practices, these templates use Prism for Xamarin Forms. Currently the templates support DryIoc and Unity for Dependency Injection. Autofac and Ninject will be added back in once there is a publicly available release of Prism 7.

TabbedPages

Working with TabbedPages has traditionally been one of the more challenging areas of working with Prism. With the QuickStart template this challenge disappears. The template includes two base implementations for a TabbedPage, the PrismTabbedPage and the DynamicTabbedPage. If your TabbedPage inherits from PrismTabbedPage, it will automatically pick up and pass on the NavigationParameters to the Child Pages allowing you to properly initialize them. If you use the DynamicTabbedPage you only need to reference it in your Navigation URI and pass in variables like:

NavigationService.NavigateAsync("TabbedPage?tab=ViewA&tab=ViewB&tab=ViewC");

But it actually gets a little better than that because not only does it pick up tabs but you can also do some deep linking like:

NavigationService.NavigateAsync("TabbedPage?tab=NavigationPage/ViewA/ViewD&tab=NavigationPage/ViewB&tab=ViewC");

This means you can actually support scenarios where your actual tabs contain their own NavigationStack independent of the rest of the application.

App Icons

Applications need a lot of icons and really the templates out there don't do a very good job with App Icons. Most templates out there just leave your deployed app with a broken icon image and require some time getting the icons setup. These templates start you off with icons for your Android and iOS projects. But more than that is the GettingStarted document included in the template gives you the information you need to be able to quickly and efficiently generate a full icon set that you can drop in to replace the default icons with your own icons. Following along with Best Practices, you'll find that the iOS project is using the newer appiconset approach with the app icons as ImageAssets rather than having them in the Resources folder as BundleResources. Similarly on Android you'll find the app icon's are all in the mipmap folders rather than drawable.

Material Design

While my purpose is not to teach Material Design, there are some basics that we can easily include in the template to get you started down the right path. That includes a basic color pallet with information of how to choose new colors. There is also already a Style defined for you to customize the look and feel of a NavigationPage using those colors.

Localization

One of the things I hear over and over, developers in the United States forget some people don't speak English. For most US based dev's Localization is a complete and total afterthought. Interestingly nobody seems to have thought previously that maybe we should provide a template that assumes you want your application easily consumable by people in another country who speak another language. The quickstart template comes complete with all of the helper classes you need to get Localization working in the application and gets the Localization implemented with the DI container using Prism's IPlatformInitializer. There is also a XAML extension provided so all you need to do is include the namespace in your XAML file and use it as needed. The app of course also includes a single Resx file to get you started. You simply need to add the string resources you want to use in your application.

Cross Platform

It might seem weird when we're talking about Xamarin, but seriously it gets frustrating when we're working with a Cross Platform technology and then the developer experience is completely and totally different depending on which platform you are on. One of the most common issues we can see from a templating standpoint is that if I click File -> New, it shouldn't matter whether I'm on Mac or PC, I should be able to decide if I want my project to include iOS, Android, UWP. That's not to say I don't understand that some time may be needed before you can build a UWP app on Mac, but you should at least be able to have the platform as an option so you can work on the codebase from either platform.

Item Templates

Also included are some Item Templates custom built for the included project templates. There are two basic types of Item Templates, Pages and Services. Note that there is currently no way for the dotnet templating engine to pick up what your base namespace is, so you do have to specify this from the command line.

Pages

By default when you call dotnet new prismitem you will get a page. It's assumed that you're using the ViewModelBase from the included Project templates. You can add flags to specify whether you want to implement INavigatingAware, INavigatedAware, INavigationAware, IActiveAware, or IDestructible. By default it implements INavigationAware. There is also a flag to indicate if the page is a Tabbed Child which will automatically implement IActiveAware and INavigatingAware. Currently supported page types include ContentPage, MasterDetailPage, TabbedPage (which inherits from the Quickstart PrismTabbedPage), and PopupPages.

Samples

dotnet new prismitem -namespace MyAwesomeApp -n LoginPage
dotnet new prismitem -namespace MyAwesomeApp -page PopupPage -n SomePage
dotnet new prismitem -namespace MyAwesomeApp -n CustomerDetailPage -child

Services

Chances are your app is probably using some sort of service and if you like testability like I do, then you'll really appreciate that you can create a service with Mock class that will automatically be picked up by the Quickstart template simply by building with the Mock configuration. 

Samples

dotnet new prismitem -item Service -namespace MyAwesomeApp -n LoginService
dotnet new prismitem -item Service -namespace MyAwesomeApp -n LoginService -mocks false

Secrets

All apps have secrets and other variables that we just don't want checked into source control. To better assist with this, the template includes some helpers that will regenerate the Secrets.cs with sensitive variables you want in your codebase. Both the Secrets.cs and secrets.json files have also been added to the included .gitignore, so you can finally develop apps without having to tackle the issue of keeping app secrets out of SCM.

secrets.json

{
  "AuthClientId": "{Your App Client Id}",
  "AppServiceEndpoint": "https://appservicename.azurewebsites.net/"
}

Secrets.cs

namespace YourProject.Helpers
{
    internal static class Secrets
    {
        internal const string AuthClientId = "{Your App Client Id}";

        internal const string AppServiceEndpoint = "https://appservicename.azurewebsites.net/";
    }
}

PropertyChanged.Fody

Part of the MVVM pattern is working with INotifyPropertyChanged. Unfortunately the code can get a bit tedious. 

public class ViewAViewModel : BindableBase
{
    private string _title;
    public string Title
    {
        get => _title;
        set => SetProperty(ref _title, value);
    }

    private MyModel _selectedItem;
    public MyModel SelectedItem
    {
        get => _selectedItem;
        set => SetProperty(ref _selectedItem, value, onChanged: OnSelectedItemChanged);
    }

    private void OnSelectedItemChanged()
    {
        // Do Stuff
    }
}

With PropertyChanged.Fody already included our ViewModels and other Observable objects simply become:

public class ViewAViewModel : BindableBase
{
    public string Title { get; set; }

    public MyModel SelectedItem { get; set; }

    private void OnSelectedItemChanged()
    {
        // Do Stuff
    }
}

Mobile Center

Also bundled into this template is support for the Azure Mobile Center. While this is an opt in feature you can pass in your App Secret for iOS and/or Android from the command line with everything already wired up to send your analytics and crash data to the Azure Mobile Center. This includes an implementation of ILoggerFacade that will create a Mobile Center Analytics Event.

Data Providers

Apps today are so often really connected apps. The Quickstart Template provides you a fully functional TodoApp with the option to use either the Azure Mobile Apps Client with AzureMobileClient.Helpers or to use Realm. Either data provider will start you out with the ability to quickly develop your app with full online/offline sync with the bare minimum of configuration. 

Azure Mobile Client

In addition to simply using the Azure Mobile Client you can additionally decide if you want to use anonymous authentication or if you will require some sort of authentication. If you choose an authentication provider, the Quickstart will provide you base classes for everything you need to get started. This includes scaffolding for custom authentication sources and a fully working implementation for Azure Active Directory B2C with support coming for AAD, Google, Facebook and Microsoft Accounts.

Plugins

Because the full working app uses a PopupPage for the TodoItem detail page, the Quickstart includes Prism.Plugin.Popups, and also optionally includes a Barcode Scanning Service utilizing ZXing.Net.Mobile and is fully registered and configured.

Getting Started

To get started with the templates it's recommended that you install version 2.0 pre3 of the dotnet cli as this contains several fixes in the templating engine. Once that is installed you can install the templates by using the following commands in your cli.

dotnet new -i "Prism.Forms.QuickstartTemplates::*"

You should see the prismitems and prismformsempty templates. The Quickstart template is grouped with the empty template, though you may not see it listed it is still there.

# See the Help and options for the Quickstart Template
dotnet new prismforms -h

#Create your first quickstart
mkdir Contoso.AwesomeApp
cd Contoso.AwesomeApp
dotnet new prismforms -id com.contoso.awesomeapp -fr netstandard1.6 -mc -ios-secret 
     "{your ios secret}" -android-secret "{your android secret}" -data AzureMobileClient 
     -auth AADB2C -client-id "{your AADB2C application id}"
#Be sure the B2CName in secrets.json matches your AAD B2C name

 

Why you aren't attracting or keeping Top Talent

I'm personally contacted by anywhere from 5-20 recruiters a week, and honestly well over 90% of the job "opportunities" do nothing more than make me laugh so hard, milk would squirt out of my nose (if I was drinking milk). The reality of it is, that it doesn't much matter whether you're looking for C2C, W2, or 1099, the top talent out there is laughing your offers all the way to trash (much more often than you think). Thanks to the digital world, they didn't even get the satisfaction of crumpling it up and realizing why they're in IT and not the NBA.

What Is Top Talent

What is top talent anyway? While we can get into a debate on how to define "Top Talent", I would generically define top talent as someone who possesses the following qualities:

  • They have the all or most of the expertise that you need today, and can quickly pick up any missing pieces.
  • They have a drive to always be learning. This ensures that they always be able to handle your needs as needs evolve through an ever changing world.
  • They appear to be a workaholic to most people, because they love what they do.

Why Top Talent Ignores Offers

So why then does Top Talent ignore so many offers? Well for starters you need to understand who you're dealing with. I was recently reading a great post from Scott Hanselman on the topic of 'Attending Your First Conference'. In his post he posted a number of helpful pointers from the community on Twitter. While the topic itself has nothing to do with your hiring Top Talent, it does expose a reality in the IT world as a whole. The reality is most people in IT, and especially programmers are Introverts. It's not that you can't put us in a room and expect us to have a conversation with anyone at all, but most of us probably prefer not to.

Our company culture is important to us, and we would lose that if employees weren't in the office.

Now I've heard a number of CEO's and other managers discuss reasons why they insist on their staff being on site. I will admit that in certain cases I even see valid arguments for having at least some of your staff in close enough proximity that they could come into the office for an emergency, or on some sort of periodic basis like for Monday meetings or on a rotating schedule with other programmers. The reality of it though, is that if your answer is something like the more common reasons I hear, you're losing out on the top talent when you don't need to.

We insist that our employees work from the office to promote a better sense of communication and collaboration.

The On-Prem verses Remote really touches a couple of issues. Of course it goes back to the natural state of most programmers to be introverts, but it really goes deeper than that. In the event that I live a half an hour away from the office, "Rush Hour" makes that at least an hour unless there was an accident and it suddenly takes two hours. So now you are asking a workaholic to devote an extra 2-3 hours of their day to showing their face, they didn't want to show in the first place, on an 8 hour day that was probably closer to 10-12 hours. They've now lost a chance to have a life and will likely burn out and leave. 

When we find the right talent, we'll pay relocate them even if we have to move them cross country (or help them get a Visa).

So your 'On-Prem' mentality just prevented you from hiring the Introverts, and the candidate might have said yes is burning out. That still doesn't cover it all though. The next thing you have to look at is the candidate pool. You might be based in the Bay Area or New York City and think I'm in this super Urban area with tons of programmers. Nothing says that the right person for your company is located where you are. Besides with a lot of specialties it's easy to quickly end up looking for a Unicorn. Honestly this is probably the quickest way to get ignored by Top Talent. Let's just be honest most of us care about our friends and our family. We probably have roots where we are and we don't feel like being uprooted from our lives, or uprooting the lives of our spouse and kids because you read some mantra about "Company Culture".

Attracting (and KEEPING) Top Talent

If you want to attract the Top Talent you need to spend some time taking inventory. You might be surprised what you find. If you take the time to address the following issues, the Top Talent out there will take notice.

  • Don't Freak Out! Take an inventory of what your current company culture is. Chances are your open floor plan with your programmers is still quiet like a library with only the sound of the keyboards as your programmers are chatting via Slack or Skype for Business. All that's left is to let them work remotely.
  • Offer Top Talent the ability to work Remotely even when it means you need to fly them into the office periodically for meetings or corporate events.
  • Be prepared to pay for Top Talent, but don't focus on Salary. Nobody likes being asked how much they expect. The reality is they want to tell you $1,000,000, but figure you'll only pay $120,000. You wish you could legally pay them $10,000, but you are prepared to pay $140,000. Another company offers them $135,000 and they're out the door. The truth is while there might still be some negotiation on salary, this classic paradigm is from a culture that no longer exists. Be prepared to tell them upfront what you are prepared to do. If what you're thinking is too low they'll tell you. 
  • Benefits matter. The simple fact is if you offer $120,000 base salary and another company offers $130,000 base that doesn't mean Top Talent is automatically going for the higher base. 
    • Health Insurance: Think about what you offer. You'd be surprised at how many recruiters and HR Managers I've talked to couldn't answer questions like "Do you offer a PPO or HMO". Another huge point, does the company bear the full cost of the insurance or is it a shared expense with the employee? That could make all the difference in the world.
    • Tuition reimbursement. Just because you're looking for Top Talent, doesn't mean that they don't have student loans. If your company is willing to help them pay it off, don't be shy.
    • PTO: If you start your employees off with 4 weeks of PTO instead of the classic 2 weeks, seriously rethink your job posting that just says benefits include "PTO". Chances are Top Talent will take a pay cut just for the ability to spend time doing what they love with the people they love.
  • If you expect some Loyalty, be prepared to reciprocate and have some examples of how the Company values Loyalty to it's employees, contractors and consultants. 
  • Show you care as much about continuing education as they do. Don't wait for them to ask/beg, offer to pay for their time and all expenses for them to attend at least one or two conferences each year. 
  • Show you care about Quality of Life. 
    • Provide ample PTO without a hassle. One of my favorites came from a company that insists their developers take a week paid vacation every 12 weeks.
    • Be flexible. Every company has meetings, but provide enough work day flexibility that they can split their day up. This could mean they have the time to make their kid's soccer game, or simply that they got to clear their mind and go for a walk or a bike ride for a couple of hours. 
  • Be open, and be serious about improving. If the Top Talent candidate were to ask their prospective coworkers about working with your company, what would they say? Would they say you have an Open Door/Inbox policy? Would they say they can speak candidly to you without fear of reprisal? Do you seek feedback?

Working with Contractors and Consultants

I know you may be thinking I started off by saying it doesn't matter whether you're looking at C2C, W2, or 1099, but so far it seems like I've only talked about W2. The sad reality is that even for 1099/C2C a surprising amount of companies think that Consultants and Contracts are employees they don't pay benefits to. Everyone of course is different, but you might be surprised when you rethink how you approach contractors and consultants. If a contractor is going to charge you $100+/hr chances are you do not want to think about overtime. The problem is that you have a contract that is going to last 6 or 12 months. 

Just because you're working with a contractor doesn't mean that they don't care about the same things that your employees do. In fact for contractors it is even more critical that they have things like remote work flexible schedules. Let's be honest if you hired a contractor even when it's "Temp to Hire" you started off the relationship by saying you have no loyalty to them whatsoever. If they can't maintain an ability to attract other clients to sustain them at the end of their contract with you, they are charging you more, even if they don't tell you that. 

As sad as it is, companies so often suffer because they didn't think about the needs of the contractor. When you approach a contractor from a basis that you will pay a flat negotiated rate, and that they don't need to worry about being paid, even when they took the week to go on vacation or go to a seminar somewhere, you might be surprised at how much more you get from that contractor. Suddenly you'll have unleashed the contractor to burn the midnight oil to get things done for you, while ensuring that they can make the appropriate decisions they need to in order to put the best foot forward. 

 

Azure Mobile Client Helpers

To be honest, I forget now exactly when I first heard about the Azure Mobile Client library. I do however remember an initial sense of excitement for being able to add Online/Offline syncing to my apps. That excitement gradually faded a little when I started to deep dive into the library and realized that every project I wanted to use the Azure Mobile Client, meant that there were a number of helpers I would need to recreate. If you're familiar with the Azure Mobile Client, the chances are you may have seen tutorial either by or inspired by Adrian Hall's guide. Even Xamarin's "Connect App" template uses this basic approach. Honestly I don't mind providing an implementation for an interface or two in my projects, but it gets a little old when I have to redevelop everything in my projects.

It was for this reason that I decided to wrap the abstractions and some basic implementations into a reusable library. The AzureMobileClient.Helpers library wraps what you need to quickly get off the ground running with the AzureMobileClient. But it's really about more than simply providing the base classes you need to be successful. It's also about helping you to develop the code that follows best practices, and helps keep your code testable. 

So what does getting started even look like? Well let's say we have the classic TodoItem.

public class TodoItem : EntityData
{
    public string Name { get; set; }
    public string Notes { get; set; }
    public bool Done { get; set; }
}

We don't need to define any of the fields specific to our Azure Mobile Services Entity as it's already defined in the EntityData base class. Since I'm all about Developer Experiences, and trying to make things to where we have to write as little code as possible to have a fantastic app, I'll use Mobile Center to quickly setup a Mobile Backend. 

Create an Easy Table

Navigate to the Tables tab and create your first table. Note that when you first go to the Tables tab you'll be asked to link the app to your Azure account. The Mobile Center will automatically go out and provision a new Mobile App Service and setup everything in a Resource Group for your app. You should be aware that you can go into the Azure Portal at any time to manage the resource. When Mobile Center sets everything up it will use a SQLite database which is great for testing, and not so great for Production. If you want to set this up to be more than a demo, before you create your first table go into the Azure Portal and configure either a SQL Server connection or Storage connection under Mobile -> Data Connections. For this example we're not going to set up any authentication, but you can do this easily from Mobile Center. The great thing about Easy Tables is that the data store allows for a dynamic schema so all we need to provide for this is a table name and click Create.

Set the table name

Really with very little effort and Zero code on your part, your mobile backend is ready. Notice I said it's 'Zero code on your part', and not 'Zero code'. Behind the scenes it is setting up a Node.js backend adding the files you need. You can go into the App Service Editor at any time and make manual changes if you need to. All you need to do now is setup your Xamarin application. Keeping things simple let's set up the application using Prism with a NetStandard1.4 Core library so that we can use the latest NetStandard release of the Azure Mobile Client and the Helpers library I mentioned before.

Now in order to keep things a little easier I want to keep a singular app context that I can use so I can easily scale from 1:N models without having to update the dependencies I'm injecting into my ViewModels. To do this I'm going to reference the Container specific implementation for the library so I can more easily set this up. For this we'll use the DryIocCloudAppContext and provide our Tables very much like we would using Entity Framework and the DbContext.

public class AwesomeAppContext : DryIocCloudAppContext
{
    public AwesomeAppContext(IContainer container)
        : base(container, AppSettings.DbName)
    {
    }

    // NOTE: This must be here for the AppContext to pick up your Model Type
    // and ensure that the table is created in the SQLite store
    ICloudSyncTable<TodoItem> TodoItems => SyncTable<TodoItem>();
}

Now, we just need to register our services:

protected override void RegisterTypes()
{
    Container.Register(typeof(ICloudSyncTable<>), typeof(AzureCloudSyncTable<>), reuse: Reuse.Singleton);
    Container.RegisterInstance<IMobileServiceClient>(new MobileServiceClient(AppSettings.BackendUri));
    Container.Register<AwesomeAppContext>(Reuse.Singleton);

    Container.RegisterTypeForNavigation<NavigationPage>();
    Container.RegisterTypeForNavigation<MainPage>();
    Container.RegisterTypeForNavigation<TodoItemDetailPage>();
}

With our services we're all set. We just need to add AwesomeAppContext to the constructor of our ViewModel and we can access our data. 

public class MainPageViewModel : BaseViewModel, INavigatedAware
{
    private AwesomeAppContext _context { get; }

    public MainPageViewModel(AwesomeAppContext context)
    {
        _context = context;
        TodoItems = new ObservableRangeCollection<TodoItem>();
    }

    public ObservableRangeCollection<TodoItem> TodoItems { get; }

    public async void OnNavigatedTo(NavigationParameters parameters)
    {
        await _context.TodoItems.SyncAsync();
        TodoItems.ReplaceRange(await _context.TodoItems.ReadAllItemsAsync());
    }
}

Finally we can go from idea to working app in under 10 minutes with full Online/Offline Sync. You can see the full working TodoDemo app on GitHub.

Xamarin Package Authoring

Whether you're just a .NET developer or a Xamarin developer we've all used NuGet. Chances are if you're anything like me, you may have started down the development path on some project and developed out some really awesome tools to help you. Then maybe you were in a fancy design meeting. Maybe you were busy thinking how Rome didn't become a great Empire by having meetings... 

Rome didn't have meetings

Perhaps you're more like me and you were either at Starbucks or on your way to Starbucks, and a great idea struck. Then you realized that all of the functionality you need you just implemented on this other project. Obviously the answer is to decouple the code you wrote from your last project and put it into it's own project. The problem you ran into though is that you develop on a Mac and NuGet is for PC right?

Now I could go into authoring packages with the new csproj format using dotnet pack. But truthfully that is a topic all by itself. It's actually something that many developers may not realize you can do. I mean if you go to NuGet.org all you can find is the download for the Windows exe. What people may not realize though is that it's much easier to start authoring packages using the Xamarin toolset than you may realize.

When you installed Xamarin Studio or the newly released Visual Studio for Mac along with the IDE and tooling for Android & iOS development, you actually got Mono. Now if you go to Google and search for Mono because you have no clue what I'm talking about, don't worry, we're not talking about the infectious disease. If you go down under WebMD to the Mono Project you'll see what we're talking about. Bundled in Mono is NuGet and even better the executable is already added to your path so once you open the terminal you can just execute NuGet commands. Now there is one caveat, and it is an important one. Mono for some unknown reason refuses to update the bundled version from 2.12 so you're good if you want to query a NuGet feed or pull a package, but that's pretty much it. Fear not though, you just need to run sudo nuget update -self, and it will update to the latest version the same as if you ran it on Windows. 

There are of course some gotcha's here:

  1. If you're building platform specific code that includes the full net framework like net45 you're going to have to build the source on Windows. That said if you built it on your PC but maybe had the project in your DropBox then you can pack the Windows built binary on the Mac
  2. Xamarin Studio/Visual Studio for Mac updates. The updates typically include an Update for Mono which will reset your NuGet version back to 2.12 unless they ever decide to update the bundled version so after running updates on the IDE you will need to update NuGet before packing your projects.

A Dot Net Developer on a Mac

Recently I had a chance to attend a meetup here in San Diego. To be honest, around other developers I sometimes feel like the odd man out. I mean here I am a C# Dot Net developer, and I'm showing up to code with a Mac. It really wasn't all that long ago that you might look at a "C# Developer" doing something like that, as if they were on crack. But the times they are changing. In fact, at that meetup the odd man out, was the dev with a Windows Laptop.

I often have conflicting feelings about my development. On the one hand, I absolutely LOVE Visual Studio. As far as I'm concerned it hands down beats every other IDE out there. As I mentioned though, when I'm on the go, more often than not I'm working off my Mac. So then how on earth does a Dot Net developer work on a Mac. Well truthfully if it wasn't for all of the hard work coming from Microsoft the past few years I'm not sure it would be anywhere near as pleasant as it is now.

I realize that there are still a lot of short comings with NetStandard, for one it is completely useless for Xamarin libraries that contain XAML files. That said the work that has been done around the NetStandard has been instrumental in making Dot Net even a citizen in non-Windows environments. Part of the problem with being a Dot Net developer outside of Windows is that the tooling was heavily integrated with Windows, so it wasn't as easy as install Mono... go...

I have been gleefully watching over the past couple of years as all of that has started to change. One of my recurring issues, and frankly one that may have caused me to pull out a lot of hair, was that Microsoft kept increasing the developer experience around PowerShell. Well that's cool, but everyone else in the world is using Bash and PowerShell wasn't available outside of Windows. So to me I kept asking how stupid can you be to increase the dependency on a Windows Environment? Well truth be told they were working on porting PowerShell and it is actually available for Mac and Linux now so any PowerShell commands I may have been running in the past on PC, are now available on Mac.

But it really doesn't end with PowerShell. For the past year I have been somewhat vocal about what they call "Visual Studio for Mac", or as I call it "Xamarin Studio with a Visual Studio logo". This week the team released Preview 6 for VS for Mac. For the first time Mac users like myself are getting a lot closer to some of the critical pieces that have been missing. Now you may have noticed that until now, I haven't mentioned Visual Studio Code. It's not a bad editor, in fact I use it when writing articles for this blog. It's a great environment as well for quickly working up an AspNetCore website and running it locally. But it's been a little frustrating as a Dot Net developer that there hasn't been any tooling (other than PowerShell) that would allow me to connect to Azure and deploy resources right from the IDE. Preview 6 really changes things though. First it brings tooling directly into the IDE to deploy an AspNetCore application straight to Azure whether to an existing resource or a new resource you want to create. The next piece of critical functionality of course... C# 7. It may have taken a month longer, but it's finally available on Mac, proof they really are using the same Rosyln as Visual Studio???

The Hamburger Menu with Prism Forms

How many times have you heard someone ask about a Hamburger menu in Xamarin Forms? It's a topic that comes up fairly frequently and it seems there are two distinct camps. Those who will tell you it's drop dead simple, and those who are stuck trying to figure out why if it's so simple, they can't figure it out. Honestly there are already a ton of YouTube videos and Blog Posts on the topic, so much so that I didn't want to touch the subject. However there is still a ton of confusion about the "Secret Sauce".

 

I would like to think the reality is somewhere in between. So often I find the major reason for these types of disagreement, has more to do with mis-managed expectations. For those stuck trying to figure out how to implement the Hamburger Menu, I think there are two key "gotcha's".

 

I've seen a number of blogs on the topic, but it seems like they're quick to say just use a MasterDetailPage. Ok you're done, you don't have to go home, but don't stay here. But that isn't the whole story. I've seen some blogs that do make more of a point to tell you that your Detail Page must be wrapped in a NavigationPage. But again, that just isn't the whole story.

 

So how on earth do you get that hamburger menu? Well for starters, you don't go to McDonalds (or for those in my neck of the woods, In N Out). When people ask about the "hamburger menu" they aren't asking how do you implement a slide out menu in your app. But that's what we keep telling people. In order to get the "hamburger menu", you need images. See people kept telling you it was easy. The secret sauce is to add an Icon to the Master page of the MasterDetailPage. Xamarin actually does this in their sample, but seems to gloss over the importance.

 

Since I'm a Prism guy though, let me go over the creation of a Prism App with a Hamburger Menu. I will assume you have the basic Prism App setup.

 

App.xaml.cs
public partial class App : PrismApplication
{
    public App( IPlatformInitializer initializer = null ) 
        : base( initializer )
    {

    }

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

    protected override void RegisterTypes()
    {
        Container.RegisterTypeForNavigation<NavigationPage>();
        Container.RegisterTypeForNavigation<MainPage>();
        Container.RegisterTypeForNavigation<ViewA>();
        // So on and so forth...
    }
}
You'll notice here that there are three View's I'm registering. The first is just simply the Xamarin Forms NavigationPage. There's no magic here. The next is my MainPage, which I will go more into detail. And lastly I register ViewA which is just some View that I will have as a Detail Page.

MainPage.xaml
<?xml version="1.0" encoding="UTF-8"?>
<MasterDetailPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="HamburgerMenu.Views.MainPage">
    <MasterDetailPage.Master>
        <!-- Hamburger Menu Secret Sauce... Add an Icon!!!! Make sure it's in your resources for your Platform Project -->
        <NavigationPage Title="Required Foo" Icon="hamburger.png">
            <x:Arguments>
                <ContentPage Title="Menu">
                    <StackLayout Padding="40">
                        <Label Text="{Binding UserName,StringFormat='Hello, {0}'}" />
                        <Button Text="View A" Command="{Binding NavigateCommand}" CommandParameter="Navigation/ViewA?message=Did%20you%20see%20the%20secret%20sauce%3F" />
                        <Button Text="View B" Command="{Binding NavigateCommand}" CommandParameter="Navigation/ViewB?message=Told%20you%20Prism%20Rocks%21%21%21" />
                        <Button Text="View C" Command="{Binding NavigateCommand}" CommandParameter="Navigation/ViewC?message=Does%20the%20hamburger%20make%20you%20hungry%3F%3F%3F" />
                    </StackLayout>
                </ContentPage>
            </x:Arguments>
        </NavigationPage>
    </MasterDetailPage.Master>
</MasterDetailPage>
All code means stuff, and there's a bit going on. Whether I'm coding or not, I'm generally a very light hearted kind of guy that likes to joke around. So you'll notice here the Navigation Page that I have as the MasterDetailPage.Master, has a title of "Required Foo". That is because Title is a required field for the Master, while the Icon is optional. The icon when supplied hides the title. I mentioned that a NavigationPage is a requirement for the "Hamburger Menu", but that is for the Detail, NOT the Master. I am choosing to use the NavigationPage in my Master in this sample, not because I expect actual navigation within the 'Menu', but rather because it quickly gives me the ability to add a nice Header and Toolbar Menu Items.

Now before you go all crazy trying to figure it out. You can download this zip for the Hamburger Icon assets for Android and iOS.

Prism Forms 6.3.0 Highlights

For those following Prism 6.3, it's been a while coming, but there is a lot there. Here are a few helpful things to get you going.

 

Behaviors

One of my favorite additions to Prism Forms 6.3.0 is the addition of Behaviors. First of all Prism gives you a great BehaviorBase<T> class you can use for all of your custom behaviors. But we finally have an EventToCommandBehavior that allows us to execute our ViewModel Commands when an event is triggered, and the control doesn't directly support Commands for that event. This is great for things like attaching to something like a ListView where we might want to work with the ItemTapped or ItemSelected events. You have a wide degree of flexibility here where you can choose to directly accept the EventArgs in your command or you can use a custom converter to grab the item from the EventArgs.

NavigationParameters

One of the breaking API changes you may notice is with the NavigationParameters. In the past, the NavigationParameters was based on a Dictionary which gave us the limitation that a key could only be used once in the querystring. While most of the time this was fine, there are so many cases where you just need to pass a list of something. Along with the new implementation are some great helpers including both a GetValue<T> and GetValues<T>. These are also safe to use if the key didn't actually exist so there's no more need for if( parameters.ContainsKey("foobar")) FooBar = (Foo)parameters["foobar"]. Naturally you will get a default value, so do check for `null`.

 

INavigationAware

Probably one of the most used interfaces in my Prism Forms apps, is INavigationAware. This is a major breaking change. That said, it's worth the frustration of the breaking change here. First of all INavigationAware is no longer a standalone interface. It is now actually the combination of two concepts INavigatingAware and INavigatedAware. As the verbs imply, one is based on Navigation that is about to occur, while the other is about Navigation that has occurred. One of the complaints I often heard, and frankly had myself was that with OnNavigatedTo, there was a visible UI update as my ViewModel was updating the Values that were bound on the UI. INavigatingAware with it's singular OnNavigatingTo really helps to address this problem.

 

The reason why we were seeing the UI changes was that the ViewModel never had a chance to load before we pushed the page onto the Navigation Stack. OnNavigatingTo is only called once, and only before we actually push the page to the stack. Like the sample below shows, we may have some default value that is really only there to alert the developer of a problem or is there for the design time. With the OnNavigatingTo, this value will no longer appear when the the page is actually pushed as the value of Message will update to whatever was in the NavigationParameters.
 
public class FooBarViewModel : BindableBase, INavigatingAware
{
	private INavigationService _navigationService { get; }

	public FooBarViewModel( INavigationService navigationService )
	{
		_navigationService = navigationService;
	}

	private string _message = "some default value"
	public string Message
	{
		get { return _message; }
		set { SetProperty( ref _message, value ); }
	}

	public void OnNavigatingTo( NavigationParameters parameters )
	{
		Message = parameters.GetValue<string>( "message" );
	}
}

BindableBase Update

So this one got snuck in last minute. BindableBase now allows you to specify an action when the value is changed. Also changed was the change up to call RaisePropertyChanged when a property has been changed. This becomes highly useful in a variety of situations like the with the following:
public class Person : BindableBase
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set { SetProperty( ref _firstName, value, () => RaisePropertyChanged( nameof( Name ) ) ); }
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set { SetProperty( ref _lastName, value, () => RaisePropertyChanged( nameof( Name ) ) ); }
    }

    public string Name => $"{FirstName} {LastName}";
}

IActiveAware

For long time Prism users, IActiveAware is nothing new. In fact it's been there the whole time. But for Prism Forms, it's really been useless until 6.3.0. With the addition of behaviors, 6.3.0 adds a new behavior to help with one of the major problems that we have when using any MultiPage such as a TabbedPage or CarouselPage in our application. That problem of course, how on earth do you figure out when the user is actually on your page. How to handle the Children of a MultiPage is something that we will be seeing some additional work on before the next release. But in the mean time the IActiveAware behavior really gives us a great tool. Going forward with 6.3.0, I expect we will see a lot of developers adopting a pattern of making ViewModels for children of TabbedPages like the following:
public class TabbedChildPageAViewModel : BindableBase, INavigationAware, IActiveAware
{
	private bool isInitialized = false;

	public event EventHandler IsActiveChanged;

    private bool _isActive;
	public bool IsActive
    {
        get { return _isActive; }
        set { SetProperty( ref _isActive, value, OnIsActiveChanged ); }
    }

	public void OnNavigatingTo( NavigationParameters parameters )
	{
		if( isInitialized ) return;
		isInitialized = true;

		// Implement loading logic here
	}

    private void OnIsActiveChanged()
    {
        // Do Foo
    }
}
with a TabbedPage like the following:
public partial class MyTabbedPage : TabbedPage, INavigatingAware
{
	public MyTabbedPage()
    {
        InitializeComponent();
    }

    public void OnNavigatingTo( NavigationParameters parameters )
    {
        foreach( var child in Children )
        {
            // You only need to do this on the child if any of your child pages actually implement this.
            ( child as INavigatingAware )?.OnNavigatingTo( parameters );
            ( child?.BindingContext as INavigatingAware )?.OnNavigatingTo( parameters );
        }
    }
}
With this strategy you can now both initialize your Tabbed Page Children, and handle the Activation/Deactivation events that occur when the user changes the tab. You can check out a complete example of this in the Prism Samples.

Writing Cleaner, More Concise Code with Fody

We've all written code that we looked at and said, "Wow this sucks". It's not necessarily that the code itself sucks, but perhaps we just have to make the code very verbose, and we wish there was some way we could clean it up. Just as an example I'll pick on INotifyPropertyChanged. Chances are if you work with an MVVM framework like Prism or MvvmCross, you're pretty used to this. I am a huge fan of simple, elegant, and self documenting code. The problem with INotifyPropertyChanged, is that while it's necessary, it also bloats our code, and can quickly make it a little harder to see what our real intent is.
// The standard format for a Prism ViewModel
public class MyPageViewModel : BindableBase
{
    private string _email;
    public string Email
    {
        get { return _email; }
        set
        {
            if( SetProperty( ref _email, value ) )
            {
                OnEmailChanged();
            }
        }
    }

    private bool _isValid;
    public bool IsValid
    {
        get { return _isValid; }
        set { SetProperty( ref _isValid, value ); }
    }

    public void OnEmailChanged()
    {
        IsValid = RegEx.IsMatch( Email, AppSettings.EmailRegExPattern );
    }
}
Now it's great that so many framework's give us some sort of base class we can inherit from that already implements INotifyPropertyChanged so we at least don't have to do that, but let's be honest our real intent is more like:
// First possible refactoring
public class MyPageViewModel
{
    public string Email { get; set; }

    public bool IsValid { get; set; }

    public void OnEmailChanged()
    {
        IsValid = RegEx.IsMatch( Email, AppSettings.EmailRegExPattern );
    }
}
Or even simpler like:
// Second possible refactoring
public class MyPageViewModel
{
    public string Email { get; set; }

    public bool IsValid
    {
        get { return RegEx.IsMatch( Email, AppSettings.EmailRegExPattern ); }
    }
}
The question you may have, is how can you get your code simplified like the last two examples? This is where it's important to take a moment, and look at one of those things, that most of us developers do not like to think about. Let's be honest, it's something that to most of us, is easier to consider "Magic". Often we just think about the code we write, and then it ends up a compiled library or executable. The thing is, there is all sorts of stuff we can do during compilation to manipulate our code. Fody offers some excellent tooling to do exactly this, and with their PropertyChanged library you can easily add INotifyPropertyChanged.

After installing the library, your ViewModel simply needs to add a single attribute and INotifyPropertyChanged will be 'Weaved' in.
[InjectPropertyChanged]
public class MyPageViewModel
{
    // ViewModel implementation
}
Given the above examples of what we might like to do, the generated class would look like the following:
// First refactoring generated output
public class MyPageViewModel : INotifyPropertyChanged
{
    string email;
    public string Email
    {
        get { return email; }
        set
        {
            if( email != value )
            {
                email = value;
                OnEmailChanged();
                OnPropertyChanged( "Email" );
            }
        }
    }

    bool isValid;
    public bool IsValid
    {
        get { return isValid; }
        set
        {
            if( isValid != value )
            {
                isValue = value;
                OnPropertyChanged( "IsValid" );
            }
        }
    }

    public virtual void OnEmailChanged()
    {
        IsValid = RegEx.IsMatch( Email, AppSettings.EmailRegExPattern );
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
Or the second preferred example:
// Second refactoring generated output
public class MyPageViewModel : INotifyPropertyChanged
{
    string email;
    public string Email
    {
        get { return email; }
        set
        {
            if( email != value )
            {
                email = value;
                OnPropertyChanged( "Email" );
                OnPropertyChanged( "IsValid" );
            }
        }
    }

    public bool IsValid
    {
        get { return RegEx.IsMatch( Email, AppSettings.EmailRegExPattern ); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
You may notice a couple of key differences here, and they will have an impact on our application. The differences can be extremely subtle. In the first example we execute an action when our Email property is updated. In the second we have no action executed but we call OnPropertyChanged for the IsValid property anytime the Email property is updated. What does all of this mean?

I fully admit I really like the syntax of the second refactoring, it is far more elegant. That said, there is a particular problem that we would face using this syntax. Take the email [email protected]', and say that the Email field is bound to an Entry field. When the user types 'j' OnPropertyChanged is called for the Email property and IsValid property. The user types 'o', again OnPropertyChanged is called for both properties. This would continue for every single character meaning that the UI would have to respond to the event for both bindings.

Now say that you use the first implementation where you call the action OnEmailChanged when the Email property is changed, and this then executes IsValid = RegEx.IsMatch( Email, AppSettings.EmailRegExPattern ). What we are really doing is checking to see if anything has really changed. Again saying that the user types 'j', the action attempts to set a value of 'false' for IsValid. Since the property already was false, OnPropertyChanged is never called and the UI never has to respond to it. In fact the user would have to have entered [email protected] before we would see OnPropertyChanged being executed for the IsValid property. Another way of putting it that we would have been telling the UI to do something 17 times, taking up CPU time that was never needed. Then we would notify the UI again when the user typed the final character.

By using a helper like Fody, we can instead write clean concise code, following the best coding practice that fits our exact situation.