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.

Using Popup Pages with Prism for Xamarin Forms

So often as mobile developers we use some sort of Popup view. Really the reasons why we want to do this simple task are pretty endless. For too long it's been something that wasn't an option for Xamarin Forms. Then came one of my favorite new packages Rg.Plugins.Popup. The only problem is that the library requires navigation through their Popup Navigation Service instead of being integrated in with the Xamarin Forms.

This creates an issue for Prism Applications. How do you navigate to Popup Pages while maintaining a proper MVVM pattern? The solution, Prism.Plugin.Popups. With Prism.Plugin.Popups, Prism based apps can now navigate to Popup Pages using the Prism INavigationService that you're already using. Best of all, there is no configuration required. The plugin adds several new extensions in the Prism.Navigation namespace, so simply adding the INavigationService to your ViewModel and using the Prism.Navigation namespace is all you need to do.
 
using Prism.Navigation;
using Prism.Commands;
using Prism.Mvvm;

namespace MyApp.ViewModels
{
	public class MainPage : BindableBase
	{
		public MainPage( INavigationService navigationService )
		{
			_navigationService = navigationService;

			NavigateCommand = new DelegateCommand( OnNavigateCommandExecuted );
		}

		INavigationService _navigationService { get; }

		DelegateCommand NavigateCommand { get; }

		private async void OnNavigateCommandExecuted() =>
			_navigationService.PushPopupPageAsync( "MyPopupPage" );
	}
}
As mentioned before we're using the INavigationService, and just like the INavigationService you'll need to register your View and/or ViewModel the same as if you're registering any other pages for your application. One caveat to this, in order to function as an extension of the INavigationService it requires specific knowledge of the Container you're using as we have to use your container to resolve the View. As a result there is a container specific implementation for each of the public containers for Prism for Xamarin Forms.

IoT Cluster with Raspberry Pi

IoT has been exploding over the past few years, and nowhere is more evident than with the community surrounding the Raspberry Pi. It is probably one of the most versatile ARM platforms being used today. With all of this support we have a wide degree of options.
 
5 Raspberry Pi 2's running in a Docker Swarm
 
Enter Docker... with the benefit of preconfigured images from Hypriot, you can now easily set up a fully functional Docker Swarm in mere minutes. For those who know about Docker, let me start by saying I don't believe you'll learn anything new from this post other than perhaps you can make it work on Raspberry Pi.

As for functionality with Docker Swarm running I was able to quickly deploy a number of services including MariaDB, PostGRE, Gogs, along with a number of other applications. It really shouldn't come as a huge surprise that you can have highly available services which are easily deployed using Docker, for me what was the most telling factor was the hardware involved.

Hardware

One of the first things you may notice about the hardware is I had no real cost for my cables or switch. That's because I pulled out a few old cables and a switch I knew I should throw out but for some reason kept.
 
Qty Item Cost
5
Raspberry Pi 2
$35/ea
5
Micro Sd Cards
$7/ea
6
Cat 5 Cables
$10
1
Old 100mb Switch
$15

Conclusions

Now I should probably say I would probably not recommend this for a larger business, but when you have an fully functional cluster of actual physical hardware that can provide Enterprise like availability, drawing very little power... I would say this is an excellent feature for small businesses which may be a little shy about having some hosting service host their data in the "Cloud".

Additional Reading

Downloads

  • Hypriot Docker Image for Raspberry Pi - Version 0.6.1 Hector - Download - Checksum - Published 11-15-2015
  • Hypriot Cluster Lab - Version 0.1 - Download - Checksum- Published 12-8-2015

Poor Man's Design Strategy for Dynamic Code in PHP

Perhaps this has happened to you. You're working on a code base and as you scroll through the code you see something like:
 
if( $foo == "bar" )
{
    $name = $foo;
    # Execute some code
}
else if( $foo == "fu" )
{
    $name = $foo;
    # Execute the same code we just did....
}
else if( $foo == "fubar" )
{
    $name = $foo;
    # Execute the same code we did the last two times...
}
// and so on....
I fully admit it drives me absolutely crazy when I see code that is complete reusable and someone decided to type it out two, three, four, or WTF were you thinking times... It's usually about the time where I am grateful I live in San Diego where we have so many great micro-breweries.

A couple of years ago I was working on a code base that had this type of just generally bad code all over the place. On top of this though was the fact that every time a new report page had to be written the Report List Page had to be updated with code like you see above. To make matters worse every time a new report category like "Admin Reports" or "Client Reports" or "Billing Reports" was added an entirely new 'else if' had to be added. The biggest problem was that the code wasn't quite like above it was more like:
 
# Admin Reports
$admin_rows = array( $stuff );

# Client
$client_rows = array( $stuff );

# Billing
$billing_rows = array( $stuff );

$table = array(
    array(
        $client_rows,
        $admin_rows
    ),
    array(
        $billing_rows
    )
);
That may not seem so bad, but this ended up in a bloated file that was in excess of 1000 lines of code.

There are always those days for a developer where you can say "and finally the day came...", and it did. Finally I had to add a new report and I refused to add to the mess. As is my style, I looked for a solution that had a certain elegance to it, something that could dynamically provide what I needed at runtime. My ultimate goal was to stop having to update the Report List page every time we added a new report.

Now to be fair here I did know a few constraints.
  • I knew the possible Report Categories that would exist
  • I knew that all of the Reports would start with the word 'Reports'
  • I knew that some reports were used more than once as a different report by passing in different parameters.

As you are probably all too familiar, if you give a thousand programmers a problem you'll get a thousand solutions. What I opted for is what I lovingly refer to as the "Poor man's Reflection Design Pattern in PHP". It's of course not quite true reflection but a design pattern that allows us to look at our project's classes for a known attribute to assist us.

Step 1:


The first thing that I needed was some way of identifying what a particular report was. For this I opted to create an array of hash-tables (aka associative arrays). This allowed me to identify information about each report dynamically and use that to decide how it needed to be constructed.
class ReportsFooBar
{
    public $report_info = array(
        array(
            'category' => 'FooBar',
            'active' => 1,
            'order' => 3,
            'title' => 'Foo...',
            'description' => 'When things are foo bar',
            'request' => '?bar=true'
        )
    );

    # some more code...
}

Step 2:


Implement the "Poor man's reflection design pattern". This looks at the php classes in a defined space. To save a few processing cycles we discard any classes which did not meet our requirement for starting with Reports. Then we load this into a hash table that will let us get the information we collected to build out our view.
# Load the local php files with a name containing 'Report'
# Setup an empty array of reports we will need to build our view for our reports
$reports = array();
foreach( $file_array as $key => $filename )
{
    # Do some cleanup to get the filename as a class name
    $report = new $filename();
    $report_info = $report->{'report_info'};

    # $report_info was not declared in our report class
    if( !$report_info ) continue; 

    # Add report to the report hash
    for( $i = 0; $i < count( $report_info ); $i++ )
    {
        # Set report at $reports[category][order]
        $reports[strtoupper[$report_info[$i]['category']]][(int)$report_info[$i]['order']] = array(
            'title' => $report_info['title'],
            'description' => $report_info['description'],
            'request' => $report_info['request']
        );
    }
}

Bonus Step:

The end result ultimately needed on additional step as you saw above we were doing the same thing over and over. Ultimately for as clever as my solution was to discover reports, it still wasn't good enough. To finish I had to literally make my variable name a variable itself. While I cannot get into the full implementation here, it looked something like:

foreach( $reports as $category => $report_info )
{
    ${"{$category}_row"} = array();
    ${"{$category}_cell"} = array();
    # do foo...
}