You are on page 1of 76

GraphQL, VS Code, Machine Learning, CSLA, Azure

MAR
APR
2020
codemag.com - THE LEADING INDEPENDENT DEVELOPER MAGAZINE - US $ 8.95 Can $ 11.95

Visiting the World


of Quantum
Computing
via FX on Hulu’s
New Show “Devs”
April attendees registering by March 20
will receive a Disney park ticket
at twilight

@DEVintersection
@AzureAIConf

DEVintersection.com 203-264-8220 M-F, 9-4 EDT AzureAIConf.com


SPRING & FALL DATES
April 6–9, 2020
Workshops April 5, 6, 10
Orlando, FL
WALT DISNEY WORLD SWAN
AND DOLPHIN

Dec 8–10, 2020


Workshops December 6, 7, 11
Las Vegas, NV
MGM GRAND

SCOTT DONOVAN SCOTT


GUTHRIE BROWN HANSELMAN
Executive Vice President, Principal DevOps Principal Program
Cloud + AI Platform, Program Manager, Manager, Web
Microsoft Microsoft Platform, Microsoft

REGISTER EARLY
for a WORKSHOP PACKAGE
and receive a choice of KATHLEEN JEFF KIMBERLY L.
DOLLARD FRITZ TRIPP
hardware or hotel gift card! Principal Program Senior Program President / Founder,
See website for details Manager, Microsoft Manager, Microsoft SQLskills
AND MANY MORE

Powered by
150+ Sessions
75+ Microsoft and industry experts
Full-day workshops Evening events
TABLE OF CONTENTS

Features
8  anage Complex Azure
M 68 CSLA .NET:
Infrastructure A Home for Your Business Logic
If you’re worried about maintaining a clear separation of business logic
You’ve got your Azure CLI set up, and you’re starting to really from the presentation and data layers, you’ll be fascinated by how
get the hang of it. Sahil shows you how to automate deployment Rockford solves the problem using CSLA (Component-based Scalable
so you can piece it all together the same way every time. Logical Architecture).
Sahil Malik Rockford Lhotka

14 J avaScript Testing in Visual Studio


CODE and Node.JS
John’s excited about how easy it is to test JavaScript in the Visual Studio
Code editor using Node.js and he shows you how you can benefit too.
Columns
John V. Petersen
62 T alk to an RD:
26 A WPF Security System Tim Huckaby and Markus Egger
When you need to make changes to a database table without updating Tim and Markus meet up after an energizing conference and chat about
your WPF applications’ security, you’ll want to see how Paul manages what’s exciting and what’s coming in artificial intelligence, and more.
this data-driven approach.
Markus Egger
Paul D. Sheriff

30 I ntroduction to GraphQL 74 Managed Coder: On Endings


Ted Neward
for .NET Developers: Mutation
Peter continues teaching you about GraphQL using the Hot Chocolate

Departments
Library. He’ll get into how to use the Entity Framework to access and
store data and explore mutations.
Peter Mbanugo

34  odman Visits the World of


R 6 Editorial
FX on Hulu’s “Devs”
Rod has the time of his life visiting the set of a new TV show about
11 Advertisers Index
developers.
Rod Paddock 73 Code Compilers
46 Introduction to Deep Learning
If you thought artificial intelligence and machine learning were exciting,
wait until you read what Wei-Meng has to say about deep learning!
Wei-Meng Lee

US subscriptions are US $29.99 for one year. Subscriptions outside the US pay $49.99 USD. Payments should be made in US dollars drawn on a US bank. American Express,
MasterCard, Visa, and Discover credit cards are accepted. Bill Me option is available only for US subscriptions. Back issues are available. For subscription information,
send e-mail to subscriptions@codemag.com or contact Customer Service at 832-717-4445 ext. 9.
Subscribe online at www.codemag.com
CODE Component Developer Magazine (ISSN # 1547-5166) is published bimonthly by EPS Software Corporation, 6605 Cypresswood Drive, Suite 425, Spring, TX 77379 U.S.A.
POSTMASTER: Send address changes to CODE Component Developer Magazine, 6605 Cypresswood Drive, Suite 425, Spring, TX 77379 U.S.A.

4 Table of Contents codemag.com


EDITORIAL

The Importance
of Community
This weekend, I was working on a session proposal (for my first conference keynote) and I came across
the code for the first coding project I wrote as a professional programmer. I guess I missed a big
anniversary in 2019—my 30th anniversary as a professional programmer. Upon reflection, there was one

item that stood out in my mind as essential to my Seattle. This is where I discovered user groups. packed room of other developers giving a talk on
success. This one item was and still is COMMUNITY. Soon after, I learned via the FOXFORUM that local using DDE (Dynamic Data Exchange) with FoxPro
software developer (and FOXFORUM member) Jeff for Windows. I succeeded and a few months later,
As many of you know, the profession of software Winchell would be demonstrating features of the I found myself in various hotels around the coun-
developer can sometimes be isolating and lonely. newest version of FoxPro at a local user group. try teaching developers FoxPro programming.
In my first two jobs, I learned this first-hand. The “Wow! This is awesome—I’m IN!” I told myself. It was at this point that I found my community
first was as a programmer for a property manage- A few nights later I was in a room full of other expanding at quick rate. I met more developers,
ment company. My job was to build applications developers getting a glimpse of software that I like Ken Getz, Paul Sherriff, Mike Gunderloy, and
to manage core functions of our business, includ- would use for many years. many others. Over many dinners in strange cities,
ing the Hot Tub Management Program. My second we shared development stories. Being a trainer
job was at a resort where I built numerous appli- I was also lucky to meet people who would change for AppDev caused the size of my community to
cations that were core to the sales and marketing my life forever. Seattle was a real hotbed of soft- grow exponentially, and from this community,
functions of a timeshare business. These included ware development and had some great develop- many opportunities presented themselves. I be-
processes like survey tracking, mailing list man- ers who were willing to share their knowledge. I came a conference speaker, a user group speaker,
agement, sales and marketing reports, and many found myself attending other user groups where author, and eventually a mentor to other mem-
others. In each of these jobs, I was the only pro- I met many people who are still friends to this bers of the community.
grammer on staff. day, like Paul Litwin, Ron Talmage, Eric Ranft,
and many others. I found myself interacting with I can say without reservation that one of the most
I didn’t have anyone to bounce ideas off or to a group of people who would go on to become important aspects of a quality life as a software
learn from. I was both the most senior and the highly respected developers in their individual developer is interaction with other developers.
most junior dev on staff. There had to be a solu- area. Many of these people became trainers, book This interaction doesn’t always need to be as co-
tion. In the late 80s, our online existence was authors, and in one case, a co-founder of Docu- workers: It can be as a part of a community of
provided via dial up into proprietary services like Sign. I felt lucky to be interacting with this group other people who do what you do. Programming
Genie, AOL and the one I chose, CompuServe. I of great software developers. doesn’t need to be a solitary endeavor.
found myself with a new account, ready to rock
my fresh new handle: 76244,3116. (This was an During this time, I continued writing code for Some items that might work for you include par-
era when we didn’t get to choose a username but various firms in the Seattle area and in 1994, I ticipating in local user groups and meetups, at-
got assigned a unique number.) found myself at a crossroads, I was getting down- tending Code Camps and/or conferences, or just
sized and decided to take the plunge and became by helping out on sites like Stack Overflow or in
My first course of action was to seek out samples an independent consultant. The community came the many listservs you can find online. Interact-
of other people’s code. I was hoping to gain in- to the rescue one more time. During my tenure ing with members of communities is an effective
sights into new coding techniques that already at Pinnacle Publishing, I met Erik Ruthruff who way to extend your skills and to enrich your life
existed and worked. Although this scratched an became a good friend and colleague. Erik intro- as a developer.
itch, it didn’t seem to fulfill what I was really duced me to many people who would influence
looking for: interaction with other programmers. my life from that point forward. (As an example,  Rod Paddock
Then I found the FOXFORUM. Erik introduced me to my awesome editor, Mela- 
nie Spiller.) About six months before my layoff,
CompuServe had various specialized area where Erik had left to work at a company in Minneapolis
users could focus conversations on particular sub- called Application Developers Training Company.
jects, known as forums. FOXFORUM was a place He told me that if I was ever interested in becom-
where FoxPro developers congregated. I partici- ing a trainer for them, I should give him a call. I
pated in this forum as a lurker. I read messages did just that and this is where the next phase of
and followed conversations in read-only mode. It community began.
took me some time to build up the courage to be-
come a more active participant. This fulfilled a part Before I could become a trainer, I needed to
of what was missing in my life: interaction with prove to myself that I could actually teach peo-
other developers, albeit in a read-only mode. It ple without running away in fright from public
didn’t take long for me to make the leap into a new speaking. I decided that my best course of ac-
type of community: software user groups. tion would be to attempt speaking at a local user
group. I contacted the leader of the local FoxPro
After toiling in the service industry of Central Or- user group and asked if I could give a talk. The
egon, I found myself moving to the “big city” of answer was affirmative. Soon, I found myself in a

6 Editorial codemag.com
OLD
TECH HOLDING
YOU BACK?

Are you being held back by a legacy application that needs to be modernized? We can help.
We specialize in converting legacy applications to modern technologies. Whether your application
is currently written in Visual Basic, FoxPro, Access, ASP Classic, .NET 1.0, PHP, Delphi…
or something else, we can help.

codemag.com/legacy
832-717-4445 ext. 9 • info@codemag.com

codemag.com
ONLINE QUICK ID 2003021

Manage Complex Azure


Infrastructure
In my previous article (https://codemag.com/Article/2001021/Azure-CLI), I introduced you to a very valuable tool called Azure
CLI. Azure CLI allows you to interact with your Azure subscription using terminal. Because it can run on a lightweight operating
system like Linux, this really opens up lots of opportunities for you. You can now author complicated scripts that deploy

complicated Azure infrastructure and run them easily and pre- Easy isn’t it? Not so fast. What if such a resource group al-
dictably from anywhere. This means that you can run them ready exists? You can issue a command like the following to
from a developer’s computer, the scripts can be shared with check whether such a resource group exists or not.
your IT pros, they can run inside of a container, or they can run
as a part of the DevOps process. You can also pair the power of az group exists -n sahil-resource
Azure CLI with Bash and write some very compelling scripts.
You can run this command and capture its output in a vari-
At the end of the day, this means that you have more free able, and write conditional logic around this in a shell script.
time and more predictability when it comes to defining and
Sahil Malik managing complex Azure infrastructure. But then we have that idiot friend who tries to run a fragile
www.winsmarts.com shell script on a Windows environment. And when it fails,
@sahilmalik Last time, I introduced various tips and tricks around Azure that friend will send an angry email and CC your manager.
CLI. The focus of this article is looking at the options around We all know how cute it is to watch managers code, much
Sahil Malik is a Microsoft
how to automate the deployment of complicated Azure in- less understand such details.
MVP, INETA speaker,
frastructure. Sure, you can use point-and-click to set up ev-
a .NET author, consultant,
erything, but do you have confidence that you can tear it all Frustrating isn’t it? But this is what real world brings us.
and trainer.
down and bring it all back up together predictably every time? For now, let’s not worry about these complications. Let’s
Sahil loves interacting with assume that my resource group has been created, and inside
fellow geeks in real time. this resource group I’m about to create a storage account.
His talks and trainings are
full of humor and practical When we talk of infrastructure Creating a storage account using Azure CLI is quite simple.
nuggets. Simply issue the command:
as code, we all know that code can
His areas of expertise are get very complex very quickly. az storage account create
cross-platform Mobile app -n sahilstorage
development, Microsoft -g sahil-resource
anything, and security -l eastus
and identity.
In this article, I’m going to pick some simple canonical ex-
amples, target the Azure cloud, and walk you through some Again, the real world comes and bites us. What if such a
options and how you can manage, create, and destroy com- storage account already exists? What if this DNS name has
plex infrastructures easily. Throughout this article, I’ll discuss been taken by somebody else in the universe? What if now I
some real-world challenges you’re going to run into. And I’ll need to make changes to the storage account?
explain how I intend to solve them. I’ll first show you how to
do this using Azure CLI, and then explain how you can do so You see, the scripts are getting more and more complicated
using Terraform, along with the advantages Terraform brings. now.

Azure CLI Terraform


Azure CLI is amazing. It’s built using the Python SDK for I’m thankful that there is a feature such as Azure CLI. But
Azure, and lets you automate nearly everything Azure has. it’s quite evident that we hit the limits of scripting very
It abstracts many details away from you, and has a simple quickly. Real-world problems have many other dimensions.
programming paradigm, but I find it to be an essential tool Here are some of the issues you’ll run into when program-
in my toolbox. ming with bare-bones Azure CLI.

For the purposes of this article, I’ll create a resource group, Some larger organizations might be in multiple clouds. Ad-
and in that resource group I’ll create a storage account. ditionally, they may want to move resources from one cloud
to another. They would appreciate having a single paradigm
First, let’s create the resource group. You can create a re- to manage infrastructure among multiple clouds.
source group using the command:
Infrastructure is never provision-and-forget. Infrastructure
az group create needs to grow iteratively over time. Anytime a change re-
-n sahil-resource quest comes in, administrators want to understand what
-l eastus would happen if a script is run before they run the script.

8 Manage Complex Azure Infrastructure codemag.com


The entire goal of all this automation is infrastructure as Terraform Basics
code. Ask your developer friends if code is a complicated I’m sure that a capable programmer like yourself will figure all
concept. Sure, all this automation allows you to manage this out. But all of these problems aren’t unique to you, and
more complicated infrastructure. But with complicated in- therefore solutions for problems like this already exist. One
frastructure comes more code. And with more code, you such solution is Terraform (https://www.terraform.io).
need to introduce concepts such as version control, auto-
mated tasks and tests, good development practices, code Terraform, at its heart, is a tool that lets you manage your
sharing, publishing/consuming packages, etc. infrastructure through its lifecycle. You describe your infra-
structure as a config file, the config file is written in JSON and
Now, you might be thinking that all of this is achievable with leverages providers to talk to various cloud providers, and
shell scripts and Azure CLI. You’re not wrong. But let me take manages provisioning, deprovisioning, maintenance, etc.
you through one of the issues I mentioned above, which is
that with more automation comes more code, which requires Terraform can be invoked via a CLI and there are three main
that real world development practices apply to infrastructure. commands involved:

Imagine that you are a developer, and you’re writing some • Refresh
shell scripts to provision some simple Azure infrastructure. • Plan
For the sake of argument, let’s say a couple of virtual ma- • Apply
chines inside a VNET. Sounds easy enough. I’m sure you
could write this up in less than an hour and the script would Refresh reconciles what Terraform thinks the real world SPONSORED SIDEBAR:
be no more than 25 lines long. looks like and reconciles it with the actual real world. In
other words, Terraform gets an actual view of what the in- Interested in Moving
Now that you’ve written such a script, you need to hand it frastructure currently looks like. to Azure?
over to your IT pro friends. What concerns would they have CODE Can Help!
in their minds? Is this going to conflict with any existing in- Plan is your “what if” equivalent. In other words, it under-
frastructure? Does this follow the best practices that you’ve stands the differences between what Terraform’s configu- Take advantage of a
FREE hour-long CODE
established with experience? Is there a rollback mechanism ration specifies the world should look like versus what the
Consulting session
if the script fails? How well-tested is the script? world actually looks like.
(yes, FREE!) to jumpstart
your organization’s plans to
I’m sure you could come up with numerous additional con- Apply is making changes to the real world based on what the develop solutions on the
cerns. The solution here is to be diligent when you write the Terraform’s configuration specifies. In doing so, Terraform Microsoft Azure platform.
script. And to be diligent when you test the script. Then you figures out the right sequence in which changes need to be For more information,
should have a bunch of meetings to ensure that everything applied. For example, various infrastructure artifacts may visit www.codemag.com/
is communicated well. And then you should remain avail- have interdependencies. Terraform automatically figures out consulting or email us at
able during production deployment. Because we all know which change should be done first, which next, which can be info@codemag.com.
that the first phone that rings is the IT pro’s, who’ll simply done in parallel, which must be done serially, etc.
forward the call to you with a bunch of curse words.
There are many other commands that Terraform supports.
Now let’s add some real dimensions to this problem. Re- For the purposes of this article, let’s stick with these three.
quirements have changed, and now suddenly you need to
add a DNS and a CDN. And you know that this isn’t the first Performing Updates with Terraform
or last time you’ll receive a change request. Now you need In this entire refresh, plan, apply circle, the guiding scroll is
to worry about versioning your scripts. And applying them the Terraform configuration that you author.
in the right sequence. Oh, and don’t forget that changes
are not just additions. Frequently, changes will be modifica- When it comes to making changes for the next deployment,
tions to existing infrastructure and deletions of some of the be it additions, deletions, or modifications, it’s just a mat-
existing infrastructure, many of which have a very particular ter of editing the configuration and re-running this refresh,
sequence in which they must be executed. plan, apply cycle. Terraform automatically understands
what needs to be left untouched, what needs changes, what
Sweating yet? needs to be removed, and what needs to be created—and in
the right sequence.
Wait. I have more. You work in a team, and your teammates
are writing scripts just like you are. How do you ensure that Finally, if you wish to tear down all of this infrastructure,
your script doesn’t conflict with theirs? Although concepts you can simply issue the delete command. This is great for
such as version control help ensure that changes in multiple managing temporary environments across dev, QA, produc-
files don’t conflict with each other, version control itself is tion, etc.
pretty much blind to what’s inside the file. That’s a job for
compilation, tests, etc. What’s even more interesting is that Terraform works
through the concept of providers. There are many providers,
Then there’s the issue that your organization may have but there’s a provider for AWS, a provider for Azure, and a
multiple clouds, possibly some on-premises infrastructure. provider for VMware. So, theoretically, you can use the same
I’m sure there’s a desire to keep things consistent between workflow across environments. I’ll admit, the real work goes
these environments and therefore manageable. in authoring the configuration file for your environment,
and that’s pretty much a rewrite for different providers. So
And let’s complicate things further with the concept of mul- don’t just magically expect your AWS environment to port
tiple environments, because why not? over to Azure or vice versa.

codemag.com Manage Complex Azure Infrastructure 9


Install Terraform provider "azurerm" {
The easiest way to use Terraform is to simply invoke Azure version = "~>1.32.0"
Cloud Shell. }

As can be seen in Figure 1, Terraform is already pre-installed You may be wondering: When you run Terraform to apply
in Azure Cloud Shell. changes to your Azure subscription, how do you authenticate
to your Azure subscription? By default, Terraform piggybacks
You can also install Terraform locally using Chocolatey for on the same authentication as Azure CLI. As I described in my
Windows or Homebrew on Mac. To install Terraform on Mac, previous article on Azure CLI, Azure CLI saves a refresh token
for instance, you simply issue the command: in its configuration files after you perform a login. It’s using
that refresh token that it gains an access token on behalf of
brew install terraform the user to whom you’d issued the az login command.

In various automation scenarios, you may want to run Ter-


Create a Configuration raform as a service principal. Even in those scenarios, Azure
Terraform configuration is one or more files that describe CLI has concepts to allow you to login as a service principal.
the desired infrastructure to Terraform. The idea is that you
declaratively describe the desired state of your infrastruc- Also, if you don’t wish to piggyback on the Azure CLI au-
ture. thentication mechanism, Terraform configuration allows
you to pass in credentials via variables as well.
The configuration files can be in either HCL or JSON. Be-
cause Terraform can work across multiple clouds using pro- But what if you wanted to run under a managed identity?
viders, a single configuration can have both Azure and AWS, Then you simply use the code snippet in your configuration
or other providers. as shown here:

You can specify which provider to work with using the fol- provider "azurerm" {
lowing syntax in a configuration: version = "~>1.32.0"

Figure 1: Using Terraform in Azure Cloud Shell

Figure 2: The first time you run refresh

10 Manage Complex Azure Infrastructure codemag.com


use_msi = true Running the plan spews out a lot of text on the screen. This
subscription_id = "" is the execution plan. Terraform is telling you exactly what it
tenant_id = "" will do to achieve your desired state for the infrastructure.
}
At the very bottom of all that text, you can see a curious
The main thing you wish to accomplish is to create resources note, like that seen in Figure 3.
in your Azure subscription. Terraform can be used to provi-
sion nearly any kind of resource in Azure. To do so, use the Generally speaking, you should always save the results of
Azure provider. It’s worth mentioning that the resources your plan as an out file. Then you can pass this file is an
specific to Azure Active Directory live in their own Azure Ac-
tive Directory provider.
Listing 1: The Terraform configuration file
For the purposes of this article, let’s go ahead and create a resource "azurerm_resource_group" "sahil" {
storage account. The full configuration for this can be seen name = "sahil-resources"
in Listing 1. Save this file as “main.tf”. I’d suggest that you location = "eastus"
create a fresh folder for it. }

resource "azurerm_storage_account" "sahil" {


Now open Terminal, navigate to the folder where you’d saved
name = "sahilstorage"
this configuration file, and run the following command: resource_group_name =
azurerm_resource_group.sahil.name
terraform init location =
azurerm_resource_group.sahil.location
The init command initializes a new or existing Terraform account_tier = "Standard"
account_replication_type = "GRS"
working directory by creating initial files, loading any re-
mote state, downloading modules, etc. This is the first com- tags = {
mand that you should run. environment = "codemag"
}
Once you’ve run this command, note that you get a new }
folder called “.terraform”. You can find the hidden folders
by running the command:

ls -alx
ADVERTISERS INDEX
It’s in this folder that the init command has downloaded
and stored the required modules. As you proceed, feel free
to explore the contents of this folder. Advertisers Index GraphQL, VS Code, Machine Learning, CSLA, Azure

Now, let’s run refresh. As I mentioned earlier, running the


MAR

CODE Consulting
APR
2020

codemag.com - THE LEADING INDEPENDENT DEVELOPER MAGAZINE - US $ 8.95 Can $ 11.95


refresh command updates the state file of your infrastruc- www.codemag.com/consulting 76
ture with metadata that matched the physical resources
they’re tracking. This command won’t modify any infrastruc- CODE Framework
ture. www.codemag.com/framework 67
Visiting the World
CODE Legacy of Quantum
Because this is the first time you’ve run Terraform refresh, www.codemag.com/legacy 7 Computing
it simply creates an empty tfstate file, as can be seen in via FX on Hulu’s
New Show “Devs”
Figure 2. CODE Magazine
www.codemag.com/subscribe 61
Performing Changes CODE Staffing
At this point, Terraform understands the environment. Now
www.codemag.com/staffing 25
it’s time to perform changes and reach the desired state. Advertising Sales:
DEVintersection Conference Tammy Ferguson
832-717-4445 ext 026
Let’s run the plan. As I mentioned earlier, the purpose of www.DEVintersection.com 2 tammy@codemag.com
the plan command is to allow Terraform to generate an
dtSearch
execution plan. The execution plan specifies what actions
www.dtSearch.com 23
Terraform will take to achieve the desired state as defined
in your configuration file, and also the specific sequence in AEC/Spar
which those actions will occur. aecnext.com or spar3d.com/event 75

Additionally, the plan command also checks the syntax of LEAD Technologies
your configuration file and the connection to Azure, and it www.leadtools.com 5
refreshes the state prior to checking for differences with the
current configuration. This listing is provided as a courtesy
to our readers and advertisers.
Let’s run the plan command: The publisher assumes no responsibility
for errors or omissions.
terraform plan

codemag.com Manage Complex Azure Infrastructure 11


Figure 3: Terraform suggesting that you use an -out parameter

terraform apply

Issuing this command clearly tells you what changes Terra-


form will perform. If you agree with the changes, say “yes”
to the prompt that Terraform offers.

Figure 4: Terraform applying your changes. Once you enter “yes,” Terraform begins applying changes,
as can be seen in Figure 4.

input parameter to the Apply command. Not only does this Once the changes are finished applying, visit your Azure por-
ensure that the execution plan is saved and perhaps version tal and verify that a storage account, as shown in Figure 5,
controlled, it also ensures consistency between multiple runs. has been created.

For the simple example, I’ll simply go with in-memory usage Day 2 Changes
and I won’t bother saving this execution plan. Congratulations. You just created a storage account. The
storage account has served you well, but notice that its
Once you know what the execution plan is, let’s go ahead replication kind has been set to GRS. This isn’t unexpected
and apply it. To do so, simply issue the command below: because this is exactly what I asked for in Listing 1.

Figure 5: Newly created storage account

Now I wish to make a change. I’d like to change the LRS, or


locally redundant storage. To do so, simply change line 11
from Listing 1 to this:

account_replication_type = "LRS"

Once you’ve saved this change, come back to Terminal and


simply issue the plan command again.

terraform plan

As expected, plan issues a refresh and it gives you a sum-


Figure 6: The specific change that will be performed. mary of exactly what changes will be performed when you

12 Manage Complex Azure Infrastructure codemag.com


Figure 7: The storage account is now locally redundant

run the apply command. Specifically, the changes can be But as this infrastructure has become increasingly complex,
seen in Figure 6. it raises new concerns. Concerns such as maintainability,
reliability, ability to replicate behavior on repeat runs, etc.
Once you’ve confirmed that this is a change you’d like to
have made, go ahead and issue the apply command. Although it’s possible to script around everything, it’s a bit
like cleaning the gym floor with a toothbrush. Being able to
terraform apply script is amazing, it’s wonderful. It certainly beats plugging
in cables and lifting heavy servers. But with utilities such as
Once the apply command is finished executing, visit the Terraform, this task becomes so much easier.
Azure portal again and verify that your storage application
has changed to locally redundant storage. This can be seen I’m sure with a combination of shell scripting, version con-
in Figure 7. trol, Azure CLI, and Terraform, you’ll be able to master some
very complex infrastructure monsters and bring them under
Deleting Resources control.
Terraform not only helps you manage the lifecycle of en-
vironments, it also helps do cleanups very easily. In the You go do that. Until next time, happy coding.
example I showed you, it was very simple. You’re welcome
to complicate the example further and provision any num-  Sahil Malik
ber of virtual machines, networks, CDNs, or any other as 
a resource you wish. It’s just a matter of creating a more
complex configuration file.

Once you’re finished playing with Terraform, Terraform can


also assist you in cleaning it all up. To clean up everything,
simply issue the destroy command as shown below:

terraform destroy

Once this command is finished executing, visit the Azure portal


again and verify that the storage account, or for that matter
everything specified in your configuration file, is now gone.

Summary
The cloud is very powerful. It’s amazing that with just a
little code, you have the ability to provision some very com-
plicated infrastructure very quickly. Of course, with great
power comes great responsibility. Infrastructure growth un-
checked will probably mean that your bill gets pretty big
too. Not only that, large complex infrastructures are now
possible and, for that matter, even desirable, when we talk
about serverless architectures.

codemag.com Manage Complex Azure Infrastructure 13


ONLINE QUICK ID 2003041

A WPF Security System


Unlike MVC or Web Forms, when using WPF, you don’t get a pre-built security system. Thus, you need to come up with your
own method of securing controls on WPF screens, such as the one shown in Figure 1. There are a few different methods to
accomplish this goal. For example, you can create different properties in your View model to make controls invisible or disabled

based on a user’s role. The problem with this approach this article, you’re going to use the {Binding Path} expres-
is that if you need to secure more controls, you need to sion to locate the control to secure as well.
change the code and then redistribute your WPF application
to your users. In this article, I’m going to take a data-driven SecurityViewModelBase Class
approach to security so you can make changes in a database When creating WPF applications, you should always use the
table and have your WPF application’s security update with- Model-View-ViewModel (MVVM) design pattern. You’re going
out having to make code changes. to create an EmployeeViewModel class in the next section,
but first, create a base class named SecurityViewModelBase
where you write code to secure controls. The EmployeeView-
Paul D. Sheriff Build an Employee Project Model class inherits from the SecurityViewModelBase class.
http://www.pdsa.com To get the most out of this article, I suggest you build the
sample as you read. Create a new WPF application using Vi- Add a new folder to the project named SecurityClasses.
Paul has been in the IT sual Studio named WPFSecuritySample. Add a new folder Right mouse-click on this folder and add a new class named
industry over 33 years. named UserControls. Right mouse-click on this folder and SecurityViewModelBase. Add the code shown in Listing 2
In that time, he has suc- add a user control named EmployeeControl. This control is to this new file. This code is just the stubbed methods you’re
cessfully assisted hundreds
where you’re going to create the screen shown in Figure 1. going to write a little later in this article, but you need to
of companies to architect
create them now so you can build the employee view model.
software applications to
solve their toughest business
Employee User Control A short description of the properties and methods you see
problems. Paul has been Create the employee user control by typing in the code in Listing 2 are described in Table 1.
a teacher and mentor shown in Listing 1. In this screen, you’re adding the Name
through various mediums property to some of the controls and the Tag property to Employee View Model
such as video courses, others. This is to illustrate that you can use either of these Create a new folder in your project named ViewModelClass-
blogs, articles, and speaking properties to locate the control you wish to secure. Later in es. Right mouse-click on that folder and add a new class
engagements at user named EmployeeViewModel. Add the code shown in Listing
groups and conferences 3 to this new file. The EmployeeViewModel class inherits
around the world. from the SecurityViewModelBase class so it can take ad-
Paul has 23 courses in the vantage of the security methods.
www.pluralsight.com library
(http://www.pluralsight. In the EmployeeViewModel class, add the individual prop-
com/author/paul-sheriff) erties to bind to the employee screen. Override the Load-
on topics ranging from ControlsToSecure() method so you can choose from where
JavaScript, Angular, MVC, to retrieve the controls to secure. For example, you may
WPF, XML, jQuery, and hard-code the controls, or retrieve them from an XML file or
Bootstrap. Contact Paul a database table.
at psheriff@pdsa.com.

Main Window
Now that you have your view model classes created, drag
the EmployeeControl user control onto the MainWindow.
Be sure to reset all layout properties so the user control
takes up the full width of your window. Your <Grid> in this
window should look like the following:

Figure 1: An Employee Information Screen <Grid>


<UserControls:EmployeeControl />
</Grid>
Property/Method Description
ControlsToSecure A list of controls you wish to secure within a WPF container Add an XML namespace to the <Window> control so you can
create an instance of the EmployeeViewModel class within
ControlsInContainer The list of controls within a WPF container the resources section of the window control.
CurrentPrincipal The current IPrincipal object for the logged-in user
xmlns:vm="clr-namespace:WPFSecuritySample
SecureControls() Call this method to secure all controls within a WPF container. .ViewModels"
LoadControlsToSecure() This method loads the list of controls to secure.
LoadControlsInXAMLContainer() This method loads all controls within a WPF container. Add a <Window.Resources> section where you can create
the definition for the employee view model, as shown in the
Table 1: The list of properties/methods in the security view model base class code snippet below.

14 A WPF Security System codemag.com


Listing 1: The XAML for the Employee screen
<UserControl Content="First Name" />
x:Class="WPFSecuritySample.EmployeeControl" <TextBox Grid.Row="2"
... // NAMESPACES HERE Grid.Column="1"
> Text="{Binding Path=FirstName}" />
<Grid> <Label Grid.Row="3"
<Grid.RowDefinitions> Grid.Column="0"
<RowDefinition Height="Auto" /> Content="Last Name" />
<RowDefinition Height="Auto" /> <TextBox Grid.Row="3"
<RowDefinition Height="Auto" /> Grid.Column="1"
<RowDefinition Height="Auto" /> Text="{Binding Path=LastName}" />
<RowDefinition Height="Auto" /> <Label Grid.Row="4"
<RowDefinition Height="Auto" /> Grid.Column="0"
<RowDefinition Height="Auto" /> Content="Salary" />
</Grid.RowDefinitions> <TextBox Grid.Row="4"
<Grid.ColumnDefinitions> Grid.Column="1"
<ColumnDefinition Width="Auto" /> Tag="Salary"
<ColumnDefinition Width="*" /> Text="{Binding Path=Salary}" />
</Grid.ColumnDefinitions> <Label Grid.Row="5"
<Button Grid.Row="0" Grid.Column="0"
Grid.Column="1" Content="SSN" />
HorizontalAlignment="Left" <TextBox Grid.Row="5"
Content="New" Grid.Column="1"
Name="NewButton" /> Tag="SSN"
<Label Grid.Row="1" Text="{Binding Path=SSN}" />
Grid.Column="0" <Button Grid.Row="6"
Content="Employee ID" /> Grid.Column="1"
<TextBox Grid.Row="1" HorizontalAlignment="Left"
Grid.Column="1" Content="Save"
Name="EmployeeID" Name="SaveButton" />
Text="{Binding Path=EmployeeID}" /> </Grid>
<Label Grid.Row="2" </UserControl>
Grid.Column="0"

Listing 2: Create a base class for all view models that need security to inherit from
using System.Collections.Generic; public IPrincipal CurrentPrincipal { get; set; }
using System.Security.Principal;
using System.Threading; public virtual void SecureControls(
using System.Windows; object element,
using System.Windows.Controls; string containerName)
{
public class SecurityViewModelBase }
{
public SecurityViewModelBase() protected virtual void LoadControlsToSecure(
{ string containerName)
ControlsToSecure = new List<SecurityControl>(); {
ControlsInContainer = new List<XAMLControlInfo>(); }
}
protected virtual void
public List<SecurityControl> LoadControlsInXAMLContainer(object element)
ControlsToSecure { get; set; } {
public List<XAMLControlInfo> }
ControlsInContainer { get; set; } }

<Window.Resources> public partial class MainWindow : Window


<vm:EmployeeViewModel x:Key="viewModel" /> {
</Window.Resources> public MainWindow()
{
Assign the DataContext attribute of the <Grid> to the in- InitializeComponent();
stance of this view model class, as identified by the key
“viewModel”. _viewModel = (EmployeeViewModel)
this.Resources["viewModel"];
<Grid DataContext="{StaticResource viewModel}"> }
<UserControls:EmployeeControl />
</Grid> private readonly EmployeeViewModel _viewModel;
}
Main Window Code-Behind
Go to the code-behind for the MainWindow class and add a Set Security Principal Object
private variable named _viewModel. Connect this variable to In order to secure your controls on each window, you need
the instance of the view model created by XAML using the to add a Loaded event to your window. From this event,
code below. call the SecureControls() method on your view model class.

codemag.com A WPF Security System 15


Open the MainWindow.xaml file and add the following key/ Try It Out
value pair in your <Window> to create the Loaded event. Run the application and you should see a screen that
looks like Figure 1. You’re now ready to start building the
Loaded="Window_Loaded" part of the code that secures the various controls on your
screen.
Listing 4 shows both the Window_Loaded() event procedure
and the SetSecurityPrincipal() method. The SetSecurityPrin-
cipal() method is where you need to create, or get, an IPrin- Goals of a Security System
cipal object and change the principal policy on the current Before you write the code to implement a security system,
thread of execution. You can either grab the current Window- let’s determine the features you need in a security system.
sPrincipal object as shown here, or you can create your own The most basic feature is the ability to make a control ap-
GenericPrincipal object by prompting a user for their user- pear or disappear based on a role. Of course, visibility in
name and password. WPF can mean either hidden or collapsed, so you most likely
want to be able to specify either. The ability to make a con-
Call the SetSecurityPrincipal() method from within the Window_ trol become disabled based on a role should be another fea-
Loaded() event. After the call to this method, call the Secure- ture in your security system. Finally, you might also want to
Controls() method on the view model passing in the instance of make input controls, such as text boxes, become read-only
this window and the name of the user control as a string. for certain roles.

Listing 3: Make all your view models inherit from the SecurityViewModelBase class
using System.Collections.Generic;
public int EmployeeID { get; set; }
public class EmployeeViewModel : SecurityViewModelBase public string FirstName { get; set; }
{ public string LastName { get; set; }
public EmployeeViewModel() : base() public decimal Salary { get; set; }
{ public string SSN { get; set; }
EmployeeID = 1;
FirstName = "Bruce"; protected override void LoadControlsToSecure(
LastName = "Jones"; string containerName)
Salary = 75000; {
SSN = "555-55-5555"; }
} }

Figure 2: Mapping security controls to controls in XAML

16 A WPF Security System codemag.com


Listing 4: Set a security principal on the thread before you attempt to secure the controls
private void Window_Loaded(object sender,
RoutedEventArgs e) private void SetSecurityPrincipal()
{ {
// Set your Security Principal // Set Principal to a WindowsPrincipal
SetSecurityPrincipal(); Thread.GetDomain().SetPrincipalPolicy(
PrincipalPolicy.WindowsPrincipal);
// Secure controls on this WPF window
_viewModel.SecureControls(this, // NOTE: You can create a GenericPrincipal here
"EmployeeControl"); // with your own credentials and roles
} }

Prepare Screen for Security To keep things simple, you’re going to create a hard-coded col-
You don’t want to have to hard-code the security on each lection of SecurityControl objects with element identifiers to
individual screen or within each view model class. Instead, match the controls in the EmployeeControl user control in your
a data-driven approach is a better choice. The way to accom- project, as shown in Figure 2. For now, you’re also just going to
plish this is to pass in a reference to a XAML element such use the Name or Tag properties to identify each control.
as a Window, a User Control, a Grid, or other container to
the SecureControls() method. All of the controls contained
within this container are read in and a unique identifier for ContainerName ElementIdentifier Mode Roles
each control is located. This unique identifier can be the EmployeeControl NewButton Collapsed Users,Supervisor
Name or Tag properties, or maybe the property name in
the {Binding Path=”propertyName”} expression. The XAML EmployeeControl EmployeeID ReadOnly Admin,Supervisor
shown below highlights the button and text box you’re go- EmployeeControl Salary Hidden Admin
ing to secure on the employee screen. Each control you want EmployeeControl SSN Disabled Supervisor
to secure must have a Name, Tag, or a {Binding} expression
EmployeeControl SaveButton Disabled Admin,Supervisor
that’s unique.
Table 2: Set of sample security data stored in SecurityControl objects
<Button Content="New" Name="NewButton" />
<TextBox Name="EmployeeID"
Text="{Binding Path=EmployeeID}" />
<TextBox Tag="Salary"
Text="{Binding Path=Salary}" />
<TextBox Tag="SSN"
Text="{Binding Path=SSN}" />
<Button Content="Save" Name="SaveButton" />

Collection of Security Objects


Table 2 shows a sample set of security data stored in a col-
lection of SecurityControl objects. This SecurityControl
collection secures the controls shown in Figure 1. For each
control, specify what Mode you wish that control to take on,
such as read-only, collapsed, hidden, or disabled. The Roles
property contains a string array of roles. If the user does
NOT belong to one of those roles, the value in the Mode
property is used to change the state of the control. For ex-
ample, if the user isn’t in a “Users” or “Supervisors” role,
the Visibility property of the control identified as NewButton
is set to “Collapsed”.

For the employee screen shown in Figure 1, you don’t want


to allow normal users of the system to be able to save any
changes to employee data. Thus, hide the “New” button and
disable the “Save” button on the screen. You also don’t want
normal users to see the salary of other employees, so make
the salary text box invisible. An administrator in your ap-
plication has the right to save employee data and to see the
salary data.

To match this set of data to the elements on your WPF Win-


dow or User Control, the ElementIdentifier property can be
the Name or Tag property of the control to secure, or the
value in the {Binding} expressions’ Path property. The Con-
tainerName property (used later in this article) is the name
of the XAML container you wish to secure. Figure 3: Classes used to secure controls on the employee screen

codemag.com A WPF Security System 17


Listing 5: The SecurityControl class holds security information about a single control WPF container control. Each row of data shown in Table 2 is
created by placing security data into a new instance of a Se-
public class SecurityControl
{ curityControl class. The Roles property is a string array, but
public string ContainerName { get; set; } there’s also a RolesAsString property that’s used to express
public string ElementIdentifier { get; set; } that Roles array as a comma-delimited list, if needed.
public string Mode { get; set; }
public string[] Roles { get; set; }
XAMLControlInfo Class
private string _RolesAsString = string.Empty; Once you have the list of controls to secure, you need to
public string RolesAsString gather a list of the controls on the WPF element you wish to
{
get { return _RolesAsString; } secure. The WPF element can be a Window, a User Control,
set { or a XAML container control such as a Grid or a StackPanel.
_RolesAsString = value; The XAMLControlInfo class (Listing 6) is the one that
Roles = _RolesAsString.Split(','); holds the information about each control within the WPF
}
} element.
}
The XAMLControlInfo class holds a reference to the con-
trol itself (TheControl), the name of the control (Control-
WPF Security Classes Name), the value in the Tag property, the type of control
You’ve already created the stub for the SecurityViewModel- (ControlType) and a Boolean flag to identify if the control
Base class, and the EmployeeViewModel class that inherits has an IsReadOnly property (HasIsReadOnlyProperty).
from it. There are two additional classes (Figure 3) you need
to create in order to be able to secure controls on any WPF There’s also a method contained in this class called Con-
screen. The first class is named XAMLControlInfo and is used to siderForSecurity(). This method returns a True value if ei-
hold information about controls within the WPF container you ther the ControlName or the Tag properties contain a val-
wish to secure. The second control is the SecurityControl class, ue. For a control to be secured, one or the other of these
which is the class to hold the information described in Table 2. properties must contain a value, otherwise there’s nothing
to match up with a value in the ControlsToSecure collection.
Both classes are added as List<T> type properties in the
SecurityViewModel class. The methods LoadControlsToSe-
cure() and LoadControlsInXAMLContainer() are responsible Security View Model Base Class
for loading each of these generic collection classes. Earlier you created the stub of the SecurityViewModelBase
class. It’s now time to write the code for the various meth-
SecurityControl Class ods you stubbed out. Before you write these methods, look
The SecurityControl class (Listing 5) holds the data to se- at Figure 4 for an overview of each of the methods called
cure a single control on a Window or User Control or other from SecureControls().

Listing 6: The XAMLControlInfo class holds information about a control within a WPF container
public class XAMLControlInfo
{ public bool ConsiderForSecurity()
public object TheControl { get; set; } {
public string ControlName { get; set; } return !string.IsNullOrEmpty(ControlName) ||
public string Tag { get; set; } !string.IsNullOrEmpty(Tag);
public string ControlType { get; set; } }
public bool HasIsReadOnlyProperty { get; set; } }

Listing 7: A hard-coded version of the LoadControlsToSecure() method


protected override void LoadControlsToSecure( {
string containerName) ContainerName = "EmployeeControl",
{ ElementIdentifier = "Salary",
base.LoadControlsToSecure(containerName); Mode = "hidden",
RolesAsString = "Admin"
ControlsToSecure = new List<SecurityControl> },
{ new SecurityControl
new SecurityControl {
{ ContainerName = "EmployeeControl",
ContainerName = "EmployeeControl", ElementIdentifier = "SSN",
ElementIdentifier = "NewButton", Mode = "disabled",
Mode = "collapsed", RolesAsString = "Supervisor"
RolesAsString = "Users123,Supervisor" },
}, new SecurityControl
new SecurityControl {
{ ContainerName = "EmployeeControl",
ContainerName = "EmployeeControl", ElementIdentifier = "SaveButton",
ElementIdentifier = "EmployeeID", Mode = "disabled",
Mode = "readonly", RolesAsString = "Admin,Supervisor"
RolesAsString = "Admin,Supervisor" }
}, };
new SecurityControl }

18 A WPF Security System codemag.com


Listing 8: The LoadControlsInXAMLContainer() method
protected virtual void if (ctl.ConsiderForSecurity()) {
LoadControlsInXAMLContainer(object element) // Is there a ReadOnly property?
{ ctl.HasIsReadOnlyProperty = element.GetType()
XAMLControlInfo ctl; .GetProperty("IsReadOnly") == null
FrameworkElement fe; ? false : true;

if (element is DependencyObject dep) { // Make sure there is not a null


ctl = new XAMLControlInfo // in ControlName or Tag
{ ctl.ControlName = ctl.ControlName ?? string.Empty;
TheControl = element, ctl.Tag = ctl.Tag ?? string.Empty;
ControlType = element.GetType().Name
}; // Add control to be considered for security
ControlsInContainer.Add(ctl);
// Cast to 'FrameworkElement' so we can }
// get the Name and Tag properties
fe = element as FrameworkElement; // Look for Child objects
if (fe != null) { foreach (object child in
ctl.ControlName = fe.Name; LogicalTreeHelper.GetChildren(dep)) {
if (fe.Tag != null) { // Make recursive call
ctl.Tag = fe.Tag.ToString(); LoadControlsInXAMLContainer(child);
} }
} }
}

The SecureControls() method is called from the code-behind role, then the state of the WPF control is modified to read-
of the WPF element/container you want to secure. or from only, disabled, or made invisible.
a command in your view model if you’re using command-
ing. The SecureControls() method calls the LoadControlsTo LoadControlsToSecure Method
Secure() and the LoadControlsInXAMLContainer() methods The LoadControlsToSecure() method builds the data shown
to populate the two properties ControlsToSecure and Controls in Table 2. This code is written in the EmployeeViewModel
InContainer, respectively. Override the LoadControlsTo class because it will change based on where you wish to
Secure() method so you can decide from which location to store the security control information. For this first exam-
load the controls to secure. For example, you may hard- ple, the data is going to be hard-coded in the LoadControls-
code the controls, retrieve them from an XML file, or load ToSecure() method, as shown in Listing 7.
them from a database table. The LoadControlsInXAMLCon-
tainer() method loops through all controls within the XAML LoadControlsInXAMLContainer Method
element you pass in and loads the ControlsInContainer In Listing 4 you passed in a reference to the current window
collection. to the SecureControls() method as shown as the first param-
eter in the code snippet below.
Once both collections have been loaded, loop through
the ControlsToSecure collection and attempt to locate the private void Window_Loaded(object sender,
control in the ControlsInContainer collection. If you find a RoutedEventArgs e)
match, check to see if the user is a part of one of the roles {
identified in the security control. If they aren’t a part of the // Set your Security Principal

Figure 4: Security method overview

codemag.com A WPF Security System 19


SetSecurityPrincipal(); "EmployeeControl");
}
// Secure controls on this WPF window
_viewModel.SecureControls(this, This reference is passed into the LoadControlsInXAMLCon-
tainer() method, shown in Listing 8 as the parameter “el-
ement”. If the reference is a DependencyObject, then you
know that you have a control that you can possibly secure.
Build a new instance of a XAMLControlInfo class and fill
in the TheControl and ControlType properties. Attempt to
cast the control as a FrameworkElement object. If the cast
succeeds, extract the Name and Tag properties. If either
of these properties are filled in, the ConsiderForSecurity()
method will return a True value.

If this control is to be added to the collection, you first de-


termine if the control has an IsReadOnly property. Next, you
make sure that the Name and Tag properties don’t contain a
null, that instead they have an empty string. This just avoids
a little extra checking later in your code. This control is then
added to the ControlsInContainer property. Any controls with-
out a Name or Tag won’t be added to the collection because
Figure 5: Employee information screen after applying security there’s no way to match it to one of the controls to secure.

Figure 6: Use different container names for each window or user control to secure.

Listing 9: The SecureControls() method


public virtual void SecureControls( c => c.Tag.ToLower() ==
object element, secCtl.ElementIdentifier);
string containerName) }
{ if (ctl != null &&
XAMLControlInfo ctl = null; !string.IsNullOrWhiteSpace(secCtl.Mode)) {
// Loop through roles and see if user
CurrentPrincipal = Thread.CurrentPrincipal; // is NOT in one of the roles
// If not, change the state of the control
// Get Controls to Secure from Data Store foreach (string role in secCtl.Roles) {
LoadControlsToSecure(containerName); if (CurrentPrincipal.IsInRole(role)) {
// They are in a role, so break out of loop
// Build List of Controls to be Secured break;
LoadControlsInXAMLContainer(element); }
else {
// Loop through controls // They are NOT in a role
foreach (SecurityControl secCtl // so change the control state
in ControlsToSecure) { ChangeState(ctl, secCtl.Mode);
secCtl.ElementIdentifier = // Break out of loop because we
secCtl.ElementIdentifier.ToLower(); // have already modified the control state
// Search for Name property break;
ctl = ControlsInContainer.Find( }
c => c.ControlName.ToLower() == }
secCtl.ElementIdentifier); }
if (ctl == null) { }
// Search for Tag property }
ctl = ControlsInContainer.Find(

20 A WPF Security System codemag.com


Listing 10: The ChangeState() method
protected virtual void ChangeState( ctl.GetType().GetProperty("IsReadOnly")
XAMLControlInfo control, .SetValue(control.TheControl,
string mode) true, null);
{ }
Control ctl = (Control)control.TheControl; else {
ctl.IsEnabled = false;
switch (mode.ToLower()) { }
case "disabled": break;
ctl.Visibility = Visibility.Visible; case "collapsed":
ctl.IsEnabled = false; case "collapse":
break; ctl.Visibility = Visibility.Collapsed;
case "readonly": break;
case "read only": case "hidden":
case "read-only": case "invisible":
ctl.Visibility = Visibility.Visible; ctl.Visibility = Visibility.Hidden;
ctl.IsEnabled = true; break;
if (control.HasIsReadOnlyProperty) { }
// Turn on IsReadOnly property }

Each control can contain other controls, so loop through Listing 11: The WpfSecurityDbContext class used by EF to get security data from a database table
any child controls and make a recursive call back to the
public class WpfSecurityDbContext : DbContext
LoadControlsInXAMLContainer() method. In this way, you {
walk through the entire control tree within the reference public WpfSecurityDbContext() : base("name=Sandbox")
to the control you passed to the SecureControls() method. {
}
SecureControls Method public virtual DbSet<SecurityControl>
The SecureControls() method, Listing 9, is called from the ControlsToSecure { get; set; }
code-behind of your WPF Window or User Control (or can be
hooked to a command). After calling LoadControlsToSecure() protected override void OnModelCreating(
DbModelBuilder modelBuilder)
and LoadControlsInXAMLContainer(), the code now loops {
through the ControlsToSecure collection and for each control, // Do NOT let EF create migrations or
it searches for the ElementIdentifier as either a ControlName // check database for model consistency
or Tag within the ControlsInContainer. If the control is found, Database
.SetInitializer<WpfSecurityDbContext>(null);
it loops through all roles to see if the user is in one of them. base.OnModelCreating(modelBuilder);
If one of the roles is found, that control is skipped. If none of }
the roles are found, the control is made invisible, read-only, }
or disabled, based on the Mode property.

ChangeState Method
If the user isn’t in one of the roles for the current con- SecurityControl Table
trol, pass in the reference to the XAMLControlInfo object Below is the T-SQL script to create a SecurityControl table
and the value in the Mode property to the ChangeState() in SQL Server. Add a SecurityControlId column that can be a
method shown in Listing 10. Extract the reference to the primary key value. Make this column an integer data type
control from TheControl property. The switch statement de- that increments automatically using the IDENTITY property.
cides what to do to the control to secure based on the mode Open an instance of SQL Server and run this script to create
parameter passed in. If the value is “disabled”, for example, this table.
then the visibility of the control is turned back on and the
IsEnabled property is set to False. If the value is “readonly”, CREATE TABLE SecurityControl (
and the control has an IsReadOnly property, that property is SecurityControlId int IDENTITY(1,1) NOT NULL
set to True, otherwise the IsEnabled property is set to True. PRIMARY KEY NONCLUSTERED,
ContainerName nvarchar(100) NOT NULL,
Try It Out ElementIdentifier nvarchar(100) NOT NULL,
Run the application and you should see a screen that looks Mode nvarchar(20) NOT NULL,
like Figure 5. RolesAsString nvarchar(1024) NOT NULL
)
In the LoadControlsToSecure() method in Listing 7, you have
a value of “Users123”. Replace that with “Users”. If you’re a After creating the SecurityControl table, enter the data
member of the “Users” group, the New button shows up when shown in Figure 6 into this table.
you rerun the WPF application.
WpfSecurityDbContext Class
Add the Entity Framework to your project using the NuGet
Secure Controls Using Database Table package manager. Open the App.config file and add a con-
Instead of hard coding the controls to secure as you did in nection string, as shown in the following code snippet.
Listing 7, create a database table where you can store the Modify the Server and Database attributes in the connection
controls to secure in your WPF application. string as appropriate for your environment.

codemag.com A WPF Security System 21


<connectionStrings> using System.ComponentModel
<add name="Sandbox" .DataAnnotations.Schema;
connectionString="Server=Localhost;
Database=Sandbox; Add the [Table] attribute just about the class definition as
Trusted_Connection=Yes;" shown in the code below. You also need to add a new prop-
providerName="System.Data.SqlClient" /> erty, SecurityControlId, to map to the primary key you added
</connectionStrings> in the SecurityControl table.

Add a new class to your project named WpfSecurityDbCon- [Table("SecurityControl")]


text, as shown in Listing 11. Modify the constructor to use public class SecurityControl
the name of the connection string you added in the App. {
config file. public int SecurityControlId { get; set; }

Modify SecurityControl Class // REST OF THE PROPERTIES ARE HERE


When you use the Entity Framework (EF), you need to deco- }
rate the class that maps to your table with a [Table] at-
tribute. Open the SecurityControl.cs file and add a using SecurityControlManager Class
statement to reference the namespace where this attribute Instead of writing EF code to access the SecurityControl
is found. table in your view model class, add a new class named Se-
curityControlManager to your project. In this class, create
a method named GetSecurityControls(), shown in Listing
Listing 12: The SecurityControlManager class gets the controls to secure from a table 12, to which you pass in the container name. The container
public class SecurityControlManager name is used if you have two or more Window or User Con-
{ trol objects in your WPF application that you wish to secure.
public List<SecurityControl> GetSecurityControls( Add a unique container name to each control in your Secu-
string containerName) rityControl table, as shown in Figure 6.
{
List<SecurityControl> ret =
new List<SecurityControl>(); LoadControlsToSecure Method
Open the EmployeeViewModel class and modify the Load-
using (WpfSecurityDbContext db = ControlsToSecure() method to create an instance of the Se-
new WpfSecurityDbContext()) curityControlManager class. Call the GetSecurityControls()
{
ret.AddRange(
method passing in the container name passed in to the
db.ControlsToSecure SecureControls() method from the Window_Loaded() event
.Where(s => s.ContainerName == procedure in the main window.
containerName).ToList());
} protected override void LoadControlsToSecure(
string containerName)
return ret;
} {
} SecurityControlManager mgr =
new SecurityControlManager();

Listing 13: The GetBindingName() method


protected virtual string GetBindingName(Control ctl)
{ if (prop != null) {
string ret = string.Empty; // Get Binding Expression
BindingExpression exp; exp = ctl.GetBindingExpression(prop);
DependencyProperty prop;
// If we have a valid binding,
if (ctl != null) { // attempt to get the binding path
// Get the unique Dependency Property if (exp != null &&
// for each control that can be used exp.ParentBinding != null &&
// to get a {Binding Path=xxx} expression exp.ParentBinding.Path != null) {
switch (ctl.GetType().Name.ToLower()) { if (!string.IsNullOrEmpty(
case "textbox": exp.ParentBinding.Path.Path)) {
prop = TextBox.TextProperty; ret = exp.ParentBinding.Path.Path;
break; }
case "label": }
prop = Label.ContentProperty; }
break; }
case "menuitem":
prop = MenuItem.HeaderProperty; if (!string.IsNullOrEmpty(ret)) {
break; if (ret.Contains(".")) {
... // MORE CONTROLS GO HERE ret = ret.Substring(ret.LastIndexOf(".") + 1);
default: }
// Add your own custom/third-party controls }
prop = GetBindingNameCustom(ctl);
break; return ret;
} }

22 A WPF Security System codemag.com


Listing 14: Add code to look for a binding path that matches a control to secure
public virtual void SecureControls(object element, ®
string containerName)
{

Instantly Search
// REST OF THE CODE HERE

// Loop through controls


foreach (SecurityControl secCtl
in ControlsToSecure) {
secCtl.ElementIdentifier =
Terabytes
secCtl.ElementIdentifier.ToLower();
// Search for Name property
ctl = ControlsInContainer.Find(
c => c.ControlName.ToLower() ==
secCtl.ElementIdentifier); dtSearch’s document filters
if (ctl == null) {
support:
// Search for BindingPath • popular file types
ctl = ControlsInContainer.Find(
c => c.BindingPath.ToLower() == • emails with multilevel
secCtl.ElementIdentifier); attachments
}
• a wide variety of databases
// REST OF THE CODE HERE • web data
}
}

Over 25 search options


including:
Getting the Sample Code
ControlsToSecure = • efficient multithreaded search
mgr.GetSecurityControls(containerName); You can download the sample • easy multicolor hit-highlighting
} code for this article by visiting
www.CODEMag.com under the • forensics options like credit
Try It Out issue and article, or by visiting card search
Press F5 to run the WPF application and you should see the same resources.fairwaytech.com/
downloads. Select “Fairway/
controls turned off as before, when they were hard-coded.
PDSA Articles” from the
Category drop-down. Then Developers:
Check for Binding Path select “ A Design Pattern • SDKs for Windows, Linux,
Normally, you don’t have to name controls in WPF because
for Building WPF Business macOS
Applications - Part 4” from the
you don’t reference them from code-behind. The TextBox con- • Cross-platform APIs for
.
Item drop-down.
trols you want to affect with security have the Text property C++, Java and NET with
with a {Binding} expression in them. You can query the bind-
ing class attached to a control and retrieve the value of the
. .
NET Standard / NET Core
Path property. This property can be used as the value in the • FAQs on faceted search,
ElementIdentifier property in your SecurityControl class. Con- granular data classification,
sider the following TextBox control with a binding expression. Azure and more
<TextBox Grid.Row="5"
Grid.Column="1"
Tag="SSN"
Text="{Binding Path=SSN}" /> Visit dtSearch.com for
Both the Tag and Text properties have the value “SSN” that you • hundreds of reviews and
can use to secure this control. Other controls in the Employ- case studies
eeControl.xaml file also have a binding and either a Name or
Tag property set. Write a method to retrieve the Path value so
• fully-functional enterprise
you can remove Name and Tag properties from the XAML where and developer evaluations
appropriate. Open the EmployeeControl.xaml file and remove
the Name property from the “EmployeeID” TextBox control. The Smart Choice for Text
Remove the Tag property from the “Salary” TextBox control.
And remove the Tag property from the “SSN” TextBox control.
Retrieval® since 1991
Add GetBindingName Method 1-800-IT-FINDS
Open the SecurityViewModelBase.cs file and add a new
method to retrieve the value of the Path property from the
www.dtSearch.com
Binding expression used on controls. The method named Get-

codemag.com A WPF Security System 23


BindingName() shown in Listing 13 uses a switch statement curity() method. Add the line shown in bold to check if the
to determine the type of control is passed to this method. For BindingPath property has a value or not.
a TextBox, you want to get the binding expression from the
Text property, so in the case statement for a text box you set public bool ConsiderForSecurity()
the variable prop to the Dependency property TextBox.Text- {
Property. Each control uses a different Dependency property return !string.IsNullOrEmpty(BindingPath) ||
based on which property you bind to most often. !string.IsNullOrEmpty(ControlName) ||
!string.IsNullOrEmpty(Tag);
Call the GetBindingExpression() method on the control, pass- }
ing in the Dependency property. If you get a value back from
this method, you check to see if the ParentBinding.Path.Path Try It Out
property has a value in it. If it does, that’s the name of the Run the WPF application and if you’ve done everything cor-
Path property you passed to the Binding expression. rectly, you should see the same controls turned off just as
they were before, even though you removed the Name and
When you’re loading the controls from the XAML container, Tag properties.
you set the BindingPath property by calling the GetBinding-
Name() method. Add the code shown in the snippet below.
Summary
protected virtual void In this article, you put together a data-driven security system
LoadControlsInXAMLContainer(object element) for WPF. Using a data-driven approach allows you to change
{ which controls to secure, generally without having to change
// REST OF THE CODE HERE any code. The code in this article does use reflection and thus
can run a little slower; however, if you’re loading a screen
// See if there are any data bindings with data, most users won’t even notice the extra half-sec-
ctl.BindingPath = GetBindingName( ond it might take to load the security information. You can
element as Control); also add some caching to this code to ensure that you only
retrieve the security data one time. I’ve used code like this
// REST OF THE CODE HERE for years in my WPF applications and it’s always worked well.
} I hope you can employ this code in your WPF applications
} when you need a security system.

GetBindingNameCustom() Method  Paul D. Sheriff


If you’re using any third-party controls, you need a method 
where you can enter those. In the “default” for the switch
statement, call a GetBindingNameCustom() method shown
below. In this method is where you can add your own cus-
tom controls and grab the appropriate Dependency property
for that control.

protected virtual DependencyProperty


GetBindingNameCustom(Control control) {
DependencyProperty prop = null;

// Add custom control binding expressions here


switch (control.GetType().Name.ToLower()) {
case "my_custom_control":
// prop = ControlType.BindingProperty;
break;
}

return prop;
}

Modify the SecureControls Method


Because the BindingPath property can now be filled into the
XAMLControlInfo class, you need to check that property to
see if it matches the ElementIdentifier property in the Con-
trolsToSecure collection. Open the SecurityViewModelBase
class and locate the SecureControls() method. Within the
loop where you search for a control by the name or tag,
insert the code shown in bold in Listing 14.

Modify ConsiderForSecurity() Method


One last change to the code you need to make to support
binding expressions is in the XAMLControlInfo class. Open
the XAMLControlInfo.cs file and locate the ConsiderForSe-

24 A WPF Security System codemag.com


codemag.com Title article 25
ONLINE QUICK ID 2003031

JavaScript Testing in VS Code


and Node.js
Periodically, I return to some aspect of how to easily test JavaScript. It seems every six months or so, new tools are available
and new techniques are developed. The goal is always the same, reduce development friction. We all seek greater productivity
by making things easier, not more complicated. In this article, I focus on how to easily test JavaScript in the Visual Studio Code

editor using Node.js as a JavaScript execution environment. In unlike XHR, is a compact way of making asynchronous
the spirit of simplicity, this article is intentionally very brief. calls and interacting with promises. For more informa-
tion on JavaScript promises, consult: https://devel-
In order to work through the examples in this article, you’ll oper.mozilla.org/en-US/docs/Web/JavaScript/Refer-
need to have Visual Studio Code and Node.js installed on ence/Global_Objects/Promise. Figure 1 illustrates the
your computer. If you aren’t familiar with Visual Studio node-fetch installation.
Code, you can learn about it here: https://code.visualstu- • make-runnable: https://www.npmjs.com/package/
dio.com/. From there, you can download and install it, and make-runnable makes it easy to run exported module
you can use their learning resources to get you up and run- functions from the command line. The idea behind
John V. Petersen ning. For Node, you can download and install from here: this module is to reduce the friction with testing Java
johnvpetersen@gmail.com http://nodejs.org. Script modules. With reduced friction comes increased
linkedin.com/in/johnvpetersen productivity. Figure 2 illustrates the make-runnable
installation.
Based near Philadelphia, Step 1: Install the Node Modules
Pennsylvania, John is an
attorney, information
Node-Fetch and Make-Runnable Step 2: Let’s Write Some JavaScript
Just as you use NuGet to extend .NET-based applications,
technology developer,
consultant, and author. you use the Node Package Manager (NPM) to extend node- Code!
based applications. The NPM packages employed in this ar- Listing 1 illustrates a simple JavaScript module. Line 1
ticle are node-fetch and make-runnable: loads the node-fetch module and line 14 loads the make-
runnable module. Lines 3-12 represent the exported Java
• node-fetch: https://www.npmjs.com/package/node- Script module. For more information on the module, con-
fetch implements the fetch API, which is an alterna- sult this resource: https://developer.mozilla.org/en-US/
tive to the old XMLHttpRequest (XHR) object. For de- docs/Web/JavaScript/Guide/Modules. If you’ve worked with
tails on fetch: https://developer.mozilla.org/en-US/ JavaScript promises in the past, you’ll appreciate the code
docs/Web/API/Fetch_API/Using_Fetch. The fetch API, efficiencies with the fetch API.

Figure 1: The node-fetch npm package installation.

Figure 2: The make-runnable npm package installation.

26 JavaScript Testing in VS Code and Node.js codemag.com


Figure 3: With the make-runnable npm package, JavaScript functions can be run easily under node.js at the command line.

Figure 4: The make-runnable module makes it easy to pass parameters to JavaScript functions.

codemag.com JavaScript Testing in VS Code and Node.js 27


Figure 5: The command palette in Visual Studio Code is accessed via the ctrl+shift+p shortcut and is the way you access common functions and extensions.

Figure 6: Clicking to your left of the line number toggles the break point for that line.

Step 3: Testing the Code from The nice thing about Visual Studio Code is that it provides
the Command Line in VS Code quick access to a PowerShell terminal. The function’s return
value is echoed to the terminal. In the real world, our Ja-
Figure 3 illustrates how to run the code from within VS vaScript functions typically require at least one parameter.
Code. You can run the code from any command prompt. Figure 4 illustrates the modified code and how to pass a
parameter in the function call.

Listing 1: JavaScript Module What About Break Points?


01: const fetch = require('node-fetch'); No testing or debugging article in the context of a full-fea-
02: tured editor, such as Visual Studio Code, would be complete
03: module.exports = { without the ability to add break points and step through
04: code. The first step to getting break points to trigger is to
05: API: function() { toggle the auto-attach feature in Visual Studio Code. Figure
06:
5 illustrates how to toggle the setting in the command pal-
07: const url = 'https://jsonplaceholder.typicode.com/todos/1';
08: const json = fetch(url) ette through the Ctrl+Shift+P shortcut.
09: .then(response => response.json());
10: return json; Once you’ve toggled the auto-attached feature, set a break
11: } point. Setting breakpoints in Visual Studio Code is done in
12: } the same way as it’s done in Visual Studio. Figure 6 illus-
13:
trates setting a breakpoint. Finally, let’s run the code and
14: require('make-runnable');
trigger the break point. For the break point to be hit, you

28 JavaScript Testing in VS Code and Node.js codemag.com


Figure 7: With the auto attach feature turned on, adding the –inspect-brk switch to the node call allows set break points to be hit.

must add the –inspect-brk switch to the node call. The mod- Learning More About VS Code
ified call is illustrated in Figure 7. With break points, you
can now inspect variables and call stacks to diagnose and VS Code is quickly becoming a very popular code editor.
fix problems with the code. In my opinion, for Web development and .NET Core
development, VS Code is much better than Visual Studio.
Over the years, Visual Studio has increasingly suffered from
Conclusion what I call feature bloat. There are many features in Visual
Studio that add to its size but go unused. Visual Studio Code
That’s really is all there is to easily test your JavaScript code
(VS Code) is lean. It’s also open sourced under the
in the Visual Studio Code editor. As you can see, if you also
MIT License. You can find the GitHub repo here:
need the ability to set break points and step through code,
https://github.com/microsoft/vscode. To learn more
that’s a very simple process as well. about the Visual Studio Code editor, check out the online
docs: https://code.visualstudio.com/docs.
 John V. Petersen


codemag.com Title article 29


ONLINE QUICK ID 2003051

Introduction to GraphQL for .NET


Developers: Mutation
GraphQL, is described as a data query and manipulation language for APIs and a runtime for fulfilling queries with existing
data. It allows varying clients to use your API and query for just the data they need, and it helps solve some issues that some
REST services have, like over-fetching and under-fetching. In my article “Intro to GraphQL for .NET Developers: Schema,

Resolver, and Query Language” (https://www.codemag.com/ CLI to add packages from NuGet. If you use Visual Studio
Article/1909061/Intro-to-GraphQL-for-.NET-Developers- and want to use the NuGet Package Manager console, run
Schema-Resolver-and-Query-Language), I wrote about the the commands listed in Figure 1 in the Package Manager
GraphQL type system, query language, schema, and resolv- Console.
er. I showed you how to build a GraphQL server using the
GraphQL .NET library and tested the API with some queries
from the GraphQL playground. In this article, I’ll introduce Designing the Schema
you to GraphQL mutation. I’ll also move off from using the You want to build an API that will allow users to query for
static method I used in that article and use Entity Framework books and their authors. You can imagine that you’re build-
Peter Mbanugo (with the in-memory provider) to access and store the data. ing this API for a small publishing company. As you may
p.mbanugo@yahoo.com already know, a GraphQL API is strongly typed, and as such,
www.pmbanugo.me In that article, I used the GraphQL .NET library to build you define types to represent what data can be retrieved
twitter.com/p_mbanugo GraphQL server in ASP.NET Core. I’ll be using the Hot Choco- from the API. Because you’re building an API about books
late library in this article. Many GraphQL APIs that are built and authors, you’ll have Book and Author types in the sche-
Peter is a software developer
who codes in JavaScript on .NET run using the GraphQL .NET currently, however, ma. You’ll be using the code-first approach to designing the
and C#. He has experience GraphQL .NET is no longer maintained and it’s not advisable schema, and for that, you’ll define POCO (plain old CLR ob-
working on the Microsoft to continue using it for new applications. The Hot Chocolate ject) types that represent these types in the schema.
stack of technologies and library is in active development and releases often. Also,
also building full-stack they have an active Slack workspace where you can ask With your project open in your preferred text editor or IDE,
applications in JavaScript. questions. That’s why I’ll be using it in this article. create a new class file Book.cs, and paste the code snippet
He is a co-chair on below into it.
NodeJS Nigeria, a Twilio
Champion, and a Project Set Up using HotChocolate;
contributor to the Hoodie You’re going to create an ASP.NET Core application to host public class Book
open source project. the GraphQL server. Open Visual Studio or JetBrains Rider {
and create a new ASP.NET Core project with the Empty tem- public int Id { get; set; }
He is the maker of Hamoni plate, or open your command-line application and follow
Sync, a real-time state the instructions below if you use VS Code. [GraphQLNonNullType]
synchronization as a service
public string Title { get; set; }
platform. He currently
1. Run the command dotnet new web GraphQL-Intro.
works with Field Intelligence,
You can replace GraphQL-Intro with your preferred proj- public int Pages { get; set; }
where he helps build a
Supply Chain Management ect name.
system that powers vaccine 2. Run the command dotnet add package HotChocolate. public int Chapters { get; set; }
and immunization distribution AspNetCore to install Hot Chocolate ASP.NET Core inte-
with Nigeria Government gration NuGet package. [GraphQLNonNullType]
as a major user. 3. Run the command dotnet add package HotChocolate. public Author Author { get; set; }
AspNetCore.Playground to add the GraphQL Play- }
When he is not coding, ground package.
he enjoys writing the 4. Run the command dotnet add package Microsoft.En- Add a new class file Author.cs and paste the code below
technical articles that you tityFrameworkCore.InMemory to add the in-memory into it.
can find on his website provider for Entity Framework.
or other publications, using HotChocolate;
such as on Pluralsight At this point, you have a basic ASP.NET Core project with the using HotChocolate.Types;
and Telerik. His current necessary dependencies needed to configure the GraphQL
focus is on Offline-First server and serve the API. The instructions use the dotnet public class Author
and GraphQL.

Figure 1: The necessary NuGet Packages

30 Introduction to GraphQL for .NET Developers: Mutation codemag.com


{ Listing 1: Declaration for the Mutation type and its resolver
using System.Threading.Tasks;
[GraphQLType(typeof(NonNullType<IdType>))]
using HotChocolate;
public int Id { get; set; } using HotChocolate.Types;

[GraphQLNonNullType] namespace GraphQL_Intro


public string Name { get; set; } {
public class Mutation
}
{
public async Task<Book> Book
In the code snippets you just added, you saw the attributes ([Service] BookDbContext dbContext, string title,
[GraphQLNonNullType] and [GraphQLType]. They’re at- int pages, string author, int chapters)
tributes from the Hot Chocolate library and you used it to {
var book = new Book
specify the type for some fields. The [GraphQLNonNullType] { Title = title,
attribute is used to indicate that a field is non-nullable. For Chapters = chapters,
example, you used it to indicate that the title field of the Pages = pages,
Book type cannot be null. The [GraphQLType] attribute is Author = new Author { Name = author }
used to set the type for a field. In this code, it’s used to };
specify that the Author Id is a non-nullable GraphQL ID dbContext.Books.Add(book);
type.
await dbContext.SaveChangesAsync();
Mutation Operations return book;
GraphQL mutation is a type of operation that allows clients }
}
to modify data on the server. It’s through this operation }
type that you’re able to add, remove, and update data on
the server. To read data, you use GraphQL query operation
type, which I covered in the article “Intro to GraphQL for
.NET Developers: Schema, Resolver, and Query Language” Listing 2: Declaration for the Query type and its resolvers
(CODE Magazine, September 2019). GraphQL specifies three using System.Collections.Generic;
root types that define the operations of a GraphQL server: using System.Linq;
using HotChocolate;
using Microsoft.EntityFrameworkCore;
• The Query type
• The Mutation type public class Query
• The Subscription type {

[GraphQLNonNullType]
The minimum a GraphQL server should define is the Query
public List<Book> GetBooks
type; the GraphQL engine you use validates the schema to ([Service] BookDbContext dbContext) =>
ensure that this requirement is met. dbContext.Books
.Include(x => x.Author).ToList();
You’re going to add a mutation that allows users to add a
//By convention GetBook() will be declared book()
new book to the application. This means that you need to //in the query type.
define the Mutation type. public Book GetBook([Service] BookDbContext dbContext,
int id) =>
Add a new file Mutation.cs and paste the code from Listing dbContext.Books.FirstOrDefault(x => x.Id == id);
1 into it. The code in Listing 1 defines a class with a method }
named Book(), which takes in some parameters. The func-
tion name will be used as the name for the field in the
schema. The first method parameter is an Entity Framework the method name and uses the remainder of the word for
DbContext object marked with the [Service] attribute. The the field name. The BookDbContext will be injected as a ser-
[Service] attribute comes from the Hot Chocolate library. vice and used to retrieve data.
Hot Chocolate supports method injection and the [Service]
attribute is used to denote that the parameter should be
injected. The rest of the parameters represent arguments Configuring the GraphQL Middleware
for that field. The code in the method contains statements So far, you’ve added code that defines the GraphQL schema
to save a new book to the database using Entity Framework. and its resolvers. The next thing you’re going to do is con-
figure the GraphQL ASP.NET Core middleware. You’ll also add
Defining Query Operations the code for the BookDbContext class that you’ve been us-
You’ve defined the Mutation type, which is the main focus ing so far.
of this article. However, you don’t yet have a Query type.
You’ll define a Query type to allow users query for the saved Add a new file BookDbContext.cs that will contain code for
books. the BookDbContext class. Copy the code below and paste
in the BookDbContext.cs file that was added following the
Add a new file Query.cs, then copy and paste the code in instruction on this line/paragraph.
Listing 2 into it. The code includes two methods GetBooks()
and GetBook(). The methods are resolver functions and will using Microsoft.EntityFrameworkCore;
be mapped to field books() and book(ID id) in the schema.
By convention, Hot Chocolate removes the word “Get” from public class BookDbContext : DbContext

codemag.com Introduction to GraphQL for .NET Developers: Mutation 31


{ Go to the ConfigureServices() method and add the code be-
public BookDbContext low to it:
(DbContextOptions<BookDbContext> options)
: base(options) services.AddDbContext<BookDbContext>(options =>
{ options
} .UseInMemoryDatabase(databaseName: “Books”));

public DbSet<Book> Books { get; set; } services.AddGraphQL(SchemaBuilder.New()


} .AddQueryType<Query>()
.AddMutationType<Mutation>()
Open Startup.cs and add the following Using statements .Create());
to the file:
This registers the GraphQL types with the GraphQL schema.
using HotChocolate; It also registers the Entity Framework DbContext to use the
using HotChocolate.AspNetCore; in-memory database provider.
using Microsoft.EntityFrameworkCore;
With the services now registered, you’ll now add the GraphQL
middleware to the pipeline so the server can serve GraphQL
requests. Add the code below to the Configure() method:

app
.UseGraphQL(“/graphql”)
.UsePlayground(“/graphql”);

The method UseGraphQL() configures the GraphQL middle-


ware and sets the path for the GraphQL API to be /graphql.
You also set up the GraphQL Playground using the UsePlay-
ground() method.

At this point, the application is ready to handle GraphQL


queries. You’re going to test the application by running it
and sending some queries through GraphQL Playground.

Test the Application


To test the application, you’re going to start it and go to
the GraphQL Playground. Open the command line and run
the command dotnet run or press F5 (or Ctrl + F5) in Visual
Studio or JetBrains Rider to start the application. Open your
browser and go to https://localhost:5001/graphql/play-
ground. This opens the GraphQL Playground UI, from which
you’ll write your GraphQL queries.

Click on the button labelled Schema at the right side of the


page and you should see the GraphQL schema displayed in
SDL, just like it is in Figure 2. You’ll notice a custom scalar
type and directive declared in the schema. This is a bug in
Figure 2: The GraphQL Schema Hot Chocolate and will be fixed soon. It shows up because

Figure 3: The GraphQL mutation result

32 Introduction to GraphQL for .NET Developers: Mutation codemag.com


Figure 4: The GraphQL query result

the directive you saw is automatically registered and that how to implement resolvers. You used the Entity Framework
also brings in the custom scalar type with it. In-Memory database provider for your data source and you
learned how to configure the GraphQL middleware.
Click on the Schema button again to close the window. Go
to the text area on the left pane and paste in the query You learned how to build a GraphQL API that has a mutation
below in it. Click the Play button to run the mutation. This and query type. This should leave you with the skills to build
should give you a success response with the saved data re- a GraphQL API to perform CRUD operations. This would al-
turned as response, as you can see in Figure 3. low you brag among your friends that you’re now a GraphQL
developer. To prove that to them, I want you to add a new
mutation{ set of functionalities to the API as follows:
book(title: “Shape Up”, chapters: 4,
pages: 100, • Add a query to find authors by their name.
author: “Anchor Duchito”){ • Allow books to have publishers. This has you add a
id new type to the schema. You should be able to inde-
chapters pendently add publishers and query for all the books
title belonging to a publisher.
author {
name If you get stuck or want me to have a look at your solution,
} feel free to shoot me a DM on twitter. I’m @p_mbanugo on
} twitter.
}
Although this skill makes you a proud GraphQL developer,
You can modify the mutation query in order to add another I’m not stopping here. In my next article, I’m going to teach
book. Then copy and run the query below to get all the you the data loader pattern and how this helps with the
books: performance in a GraphQL application. Stay tuned and keep
the coding spirit.
{
books{ You can find the completed code for this post on GitHub at
title https://github.com/pmbanugo/graphql-intro-aspnet-core.
author { Clone the repo and checkout the mutation branch.
name
}  Peter Mbanugo
} 
}

This should give you a response similar to what you see in


Figure 4.

Conclusion
I introduced you to GraphQL mutation, one of the three root
operation types in GraphQL. You created a schema using
the code-first approach. I showed you some of the attri-
butes that can be used to configure the schema and also

codemag.com Introduction to GraphQL for .NET Developers: Mutation 33


ONLINE QUICK ID 2003061

34 Rodman Visits the World of FX on Hulu’s “Devs” codemag.com


Rodman Visits the World
of FX on Hulu’s “Devs”
Being Editor in Chief of CODE Magazine is cool but the story you’re
about to read about has reached 11 on a 10 scale. Typically, my editorials,
from idea to page, have a gestation time of a few days to a few weeks
(sometimes it’s just a few hours. You know the drill, “If it wasn’t for
the last minute, nothing would get done”). Well, the piece you’re about
to read has by far the longestgestation time for any of my articles
or editorials. By the time you read this article, over 18 months will have
passed. What you’re about to read is a love story. It’s a love story where
two of my favorite worlds, film and software, collided in an epic way.

The quantum computer of the future


(Copyright 2020, FX Networks, All rights reserved. Miya Mizuno)

codemag.com Rodman Visits the World of FX on Hulu’s “Devs” 35


The “Devs” team at work on the set (Copyright 2020, FX Networks. All rights reserved. Raymond Liu/FX.)

36 Rodman Visits the World of FX on Hulu’s “Devs” codemag.com


Rod Paddock
rodpaddock@dashpoint.com
@rodpaddock
Rod Paddock is the Editor in Chief of CODE Magazine,
owner of Dash Point Software, Inc., code slinger, book
author, a darn good Dungeon Master, former film critic,
and a serious movie aficionado.

First, a Little Explanation


Quantum computing is technology based on the principles of quan-
tum theory, which explains the nature of energy and matter on
the atomic and subatomic level. It relies on the existence of mind-
bending quantum-mechanical phenomena, such as superposition
and entanglement. This gets complicated, so I asked William
Hurley (better known as Whurley), founder of https://quantum
computing.com/, to help explain. He wrote this definition.

Erwin Schrödinger’s famous 1930s thought experiment involv-


ing a cat that was both dead and alive at the same time was
intended to highlight the apparent absurdity of superposition,
the principle that quantum systems can exist in multiple states
simultaneously until observed or measured. Today, quantum
computers contain dozens of qubits (quantum bits), which take
advantage of that very principle. Each qubit exists in a super-
position of zero and one (i.e., has non-zero probabilities to be
a zero or a one) until measured. The development of qubits
has implications for dealing with massive amounts of data and
achieving previously unattainable levels of computing efficien-
cy that are the tantalizing potential of quantum computing.

Various parties are taking different approaches to quantum


computing, so a single explanation of how it works would be
subjective. But one principle may help readers get their arms
around the difference between classical computing and quan-
tum computing. Classical computers are binary. That is, they
depend on the fact that every bit can exist only in one of two
states, either 0 or 1. Schrödinger’s cat merely illustrated that
subatomic particles could exhibit innumerable states at the
same time. If you envision a sphere, a binary state would be
if the north pole, say, was 0, and the south pole was 1. In a
qubit, the entire sphere can hold innumerable other states and
relating those states between qubits enables certain correla-
tions that make quantum computing well-suited for a variety
of specific tasks that classical computing can’t accomplish. Cre-
ating qubits and maintaining their existence long enough to
accomplish quantum computing tasks is an ongoing challenge.

Quantum computers will be useful in advancing solutions to


challenges in diverse fields such as energy, finance, health-
care, and aerospace, among others. Their capabilities will
help us cure diseases, improve global financial markets,
detangle traffic, combat climate change, and more. For in-
stance, quantum computing has the potential to speed up
pharmaceutical discovery and development, and to improve
the accuracy of the atmospheric models used to track and
explain climate change and its adverse effects.

Pretty cool, huh? Well, here’s where it gets even cooler.

codemag.com Rodman Visits the World of FX on Hulu’s “Devs” 37


Sonoya Mizuno and Alex Garland think about stardust.
(Copyright 2020, FX Networks. All rights reserved. Miya Mizuno/FX.)

38 Rodman Visits the World of FX on Hulu’s “Devs” codemag.com


Here’s My Story Alex Garland—I was lucky to have the opportunity to screen
In September of 2018, Jim Duffy, the marketing director for all episodes over two days. You, kind reader, will need to be a
CODE Magazine, received an inquiry about using copies of bit more patient and watch this show starting with a double
CODE Magazine as props for a new television show being episode on March 5 (in the US on FX on Hulu), and then one
developed by FX called “Devs.” As an offhanded comment, episode each week. You can also check out more info on their
I said to Duffy, “Hey you should see if you could set up a website: https://www.fxnetworks.com/shows/devs.
set visit.” After I explained what a set visit was, Duffy made
the inquiry for me, and after 30+ e-mails, an NDA, and con- Now for the cool part. Here are excerpts from my interview
spicuous usage of hotel points and frequent flyer miles, I with Alex Garland:
was off to London for a set visit.
Rod: Literally an hour ago, I finished watching your show.
After recovering from jet lag, I took the Tube to the suburb I watched it all the way through—half of it last night—and
of Ealing in London where I soon found myself at Ealing I’m glad I had enough time to finish it today.
Studios, the oldest continuously operating film studio in the
UK and the world. I was ushered into a room where I waited Alex: Holy shit. So you got all the way to the end of episode
to have interviews with members of the cast, Nick Offerman eight?
and Alison Pill. After meeting with them, I was granted an
interview with creator-writer-director Alex Garland. Alex is Rod: Yeah, it’s bad ass. I love your show. It’s really great. I
one of my favorite writer-directors, having penned films like couldn’t stop watching it. How did this project originate?
“28 Days Later” and “Never Let Me Go” and later writing
and directing films like “Ex Machina” and “Annihilation.” I Alex: From two areas, I would say. One is just that you and I,
also got to visit the set and watch them film a couple of and everybody, live in a world where tech casts a very, very
scenes. This all occurred back in Jan of 2019 and it was a long shadow and it’s getting only longer, and so we live in a
real delight. world of very, very powerful tech companies and a very com-
plex kind of social dynamics that arise from the tech compa-
Fast-forward to Jan 2020 and here we are. I managed to binge nies, and enormous power residing with the tech companies.
all eight episodes of “Devs” before a follow up interview with That also means enormous power within machines and within

Alison Pill and Nick Offerman, stars of “Devs”


(Copyright 2020, FX Networks.
All rights reserved. Raymond Liu/FX.)

codemag.com Rodman Visits the World of FX on Hulu’s “Devs” 39


people. None of this is news. None of this is new insight. We Rod: I hear you.
all know it, but it’s the world we live in, so on some level, just
from a writing point of view, I just react to it. So that would Alex: And then on the other end, I just got really, really
then include things about the slightly cult-y feel of some tech interested in the idea of whether we do or don’t live in a
companies, and the messianic qualities of some tech com- deterministic universe, and what the implications are for us
panies, and the way in which tech companies make you feel about that. I approached these kinds of things as an athe-
often like a lot of people are drinking the Kool-Aid and that. ist. I don’t believe in God, so I start with a premise that we

Lily Chan (played by Sonoya Mizuno) contemplates her next step.


(Copyright 2020, FX Networks.
All rights reserved. Raymond Liu/FX.)

40 Rodman Visits the World of FX on Hulu’s “Devs” codemag.com


live in a physical universe, a sort of non-magical universe, how the world works. There’s nothing in our day-to-day life
and the more I read about it, the harder I found it to locate that would make us instinctively think that any physical ob-
what you would be able to call free will. It’s easy to locate ject, any piece of matter could have a superposition. Like the
what you could call an illusion of free will, but actual free idea that quantum particles have superpositions is deeply
will, that felt very hard to find. On the way to this free will, alien. It’s really, really strange, and, in a way, I can imagine
you’d need to find a bit of cause-and-effect that don’t di- that it’s not just in conflict with your experience as a software
rectly line up with each other. engineer, it’s in conflict with everybody.

Rod: Interesting. Rod: Yeah. I’m trying to wrap my head around how to even
use this technology in the future and it’s so early in it, in
Alex: You can find some of that stuff in quantum mechan- terms of how it really works.
ics, because that acts in a probabilistic way, but even that
doesn’t lead you to free will, because it would be like driving Alex: Yeah.
a car down the street and rolling the dice about whether you
turn left and right, and so you roll a six and you turn left or Rod: Yeah. There’s lots of things that have happened. It’s
you roll one to five and you turn right, the other direction. been amazing in terms of technology and kind of leading
That still wasn’t a decision that was made, that was a conse- back to your point about power in these tech companies.
quence of a bit of sort of probabilistic guide. So if you really It seems like lots and lots of very potentially hazardous
take that idea onboard that maybe you really don’t have technology has been put out into the world, things like
free will, that’s also a very interesting area for a story and deepfakes; the New York Times had an article last week
an interesting set of tools, so I hope it’s an interesting set about facial recognition software.
of tools. Then it becomes literally the way those two ideas
connect, the sort of the philosophical idea on one side and Alex: Yeah.
I guess the political idea on the other.
Rod: ...and all these technologies, yeah, and Instagram and
Rod: Okay. Wow. So in the process when you were doing all that. Do you think we’ve kind of crossed the Rubicon?
this, how did quantum computing end up in the story? Can we put this genie back in the bottle? What do you think,
even though in just the last month, so many things have
Alex: Well two reasons. One is because quantum comput- come out of the woodwork?
ing, in comparison to binary computing, has this incredible
sort of exponential amount of power attached to it the more Alex: I don’t see us putting any genies back in any bottles.
qubits you get running together. It allows for things that No. I think our best hope is that we speed up our thinking
would not be possible in classical computing terms. But the about how to deal with these issues, and we also just im-
main thing is that a quantum computer works according to prove our thinking, so not just we think faster, but we think
quantum mechanics, and the universe we live in also works better about it. I think we need to be more honest about it.
according to quantum mechanics. Instead of using classical The tech companies need to be more honest, and politicians
computing to model our world, which is quantum mechani- need to be more honest, and also the users need to be more
cal, you use a quantum mechanical system to model the honest, and make more of an effort to see it for what it is.
quantum mechanical world, and so you get something truer. So, the genie doesn’t get back in the bottle. We just need to
You’re not really able to fully model a quantum mechanical adapt better to the genie, in other words.
world in a classical way, so if you’re going to do it, you kind
of need a quantum computer, or that was my reasoning any-
way. Maybe someone who knows more about it would take
issue with that, but that’s the underlying principle. The genie doesn’t get back
into the bottle. We just need
to adapt better to the genie.
You use a quantum mechanical
system to model the quantum
mechanical world. Alex: The way I often think about it is to do with when the
world, or in fact your country, when your country decided to
reject the monarchy, and instead set up a system of democ-
racy, there was a lot of wisdom employed at that point, and
Rod: Okay. Yeah. I was just reading up on it and all the it was like recognizing what was bad about monarchy, and
discussions of Schrodinger’s cat and Heisenberg, and it’s what and how important a system of checks and balances
like, “does quantum exist?” because if you observe it, it’s was. I mean, of course, it’s more complicated than this.
different. I’m a software developer by trade, and it’s a weird It comes from many places, but to some extent, what Amer-
concept to me, because I’m so used to, if-else, right? Those ica did was create this beautiful system of checks and bal-
kinds of conditions that we deal with all the time, and then ances between the executive and the legislature and the
it’s like this, “if-else, but maybe”. It’s the whole “but may- judiciary, and it was very smart and it’s worked pretty well.
be” thing that’s weird. It’s working less well at the moment, but certainly for a long
time it worked extremely well. It seems to me that the right
Alex: It’s exactly the “but maybe.” But also, it’s not just that. thing to do is to recognize that we’re at a point in time that
The whole way the system, the quantum mechanical system, is a bit like the American Revolution; we need a system of
works is just completely at odds with our intuitive sense of careful, well-structured checks and balances—they’re not

codemag.com Rodman Visits the World of FX on Hulu’s “Devs” 41


there to remove power, but they’re there to make sure power
is dealt with properly.

Rod: How do the checks and balances relate to “Devs”?

Alex: I feel like that’s the thing that’s missing. The prob-
lem is that the tech companies exist within the capitalist
marketplace, that there is an ideology that’s rather power-
ful at the moment that says that marketplace must be kept
free. And the question is whether something that powerful
should be kept free or not, and increasingly I think anything
powerful, anything, I don’t care where, it needs limitations
on its power. And it just doesn’t feel right to set up a new
kind of monarchy where you have kings and queens, but a
tech company.

SPONSORED SIDEBAR: Rod: These are very heavy questions. So let’s ask a couple
of light questions, and there’s an area of this that I’m actu-
Your Legacy Apps ally really very curious about. One of the things that I felt
Stuck in the Past? you got very right in this story is programmers and geeks/
Need free advice on programmer culture. How did you get that so right? Because
migrating yesterday’s I mean the one thing that really stuck out to me, and it’s
legacy applications to a going to seem silly, is every single laptop I’ve owned for the
today’s modern platforms? last 15 years, it’s loaded with stickers, and I have like a box
CODE Consulting has years of them for the next laptop when it shows up, because it’s
of experience migrating like, oh, new sticker, new sticker laptop, right? And the way
legacy applications to they dress, the way they talk, the way they, how did you
modern platforms. Contact pull that off? Because I notice very few people get it right.
us today to schedule your
free hour of CODE Alex: Well, look, part of the answer to that is I worked with
Consulting call with our a big team of people, and so what you’re seeing is the sort
expert consultants of result of a den of hive thinking. Lots of people are in-
(not a sales call). volved; for example, the visual effects supervisor, Andrew
For more information, Whitehurst, he talks about stickers and laptops. Andrew’s
visit www.codemag.com/ an incredibly talented coder, although he would immedi-
consulting or email us at
ately [say] that he’s not, but he is, and I remember him
info@codemag.com.
talking about stickers on laptops. So, it partly comes from
stuff like that. And I think the other place it comes from
is possibly, maybe, or I hope I have some kind of personal
connection with that world, in as much as that when I’m
talking to people in that world, I often feel like although we
have different areas, like screenwriting or coding, there’s a
weird amount of crossover interest, so we’re sort of talking
the same language in a way. I think I sort of, maybe I get
it because there’s a large part of me that is like that, right?

Really, this is a sci-fi tech thriller.


Any well-dressed coffee table includes
a copy of CODE Magazine
Rod: There’s a lot of truth to that. Actually, a year, a year (Copyright 2020, FX Networks.
and a half ago, I wrote parallels of how our two industries All rights reserved. Courtesy FX Networks.)
work the same. We have our pre-visualization for building
mockups of stuff, and then we have the coding, and we have
the testing and the refinement, and we go back and forth,
so being a film nut and a computer guy, the crossovers have with the show, it’s like how do you classify this show? Be-
been pretty amazing. Well, you did a good job on making cause it seems like you’ve done a mashup of mystery, thrill-
it pretty accurate for how we act, and the culture that we er, horror, sci-fi, and time travel. You’ve thrown it all in and
have. melded it together very well. If you’re describing this at a
dinner party to people who don’t watch it, how do you de-
Alex: Thanks. scribe this to people? How do you classify this yourself?

Rod: I think I’ll wrap it up with just one general question. Alex: Yeah, it’s a good question. It’s sort of tricky, but I
One of the problems that I’ve had, and it’s not a problem know that it’s also, yeah, it’s like a good thing to do, be-

42 Rodman Visits the World of FX on Hulu’s “Devs” codemag.com


cause it gives people a shorthand of how to approach it. The breaking news about “Devs” using the following social me-
way I see it in my head is that it’s a sci-fi tech thriller. So dia info:
in a way, in the definition, I’d do the mashup you’re talking
about, because you could say it’s a thriller, you could say it’s @Devs_FXonHulu
a tech movie, you could say sci-fi, but really, this is a sci-fi #Devs
tech thriller. #FXonHulu

Remember to check out “Devs” on FX on Hulu. See if you  Rod Paddock


can find CODE Magazine on the show. You can also follow 

codemag.com Rodman Visits the World of FX on Hulu’s “Devs” 43


ONLINE QUICK ID 2003071

Introduction to Deep Learning


Artificial intelligence (AI) is one of the hottest topics these days. With the advancement in hardware technologies, it’s now
possible to do things that were once deemed impossible. Autonomous driving is no longer a dream, and fully autonomous
driving is fast becoming a reality. A subset of AI is machine learning, and deep learning is a subset of machine learning.

In my earlier two articles in CODE Magazine (September/ • Output layer: The output of the neural network is the
October 20017 and November/December 2017), I talked predictions that you’re trying to get out of the net-
about machine learning using the Microsoft Azure Machine work.
Learning Studio, as well as how to perform machine learn-
ing using the Scikit-learn library. In this article, let’s turn Each node in a layer connects to all the other nodes in the
our attention to one of the most exciting (if not seemingly next layer. Each connection between nodes has a value
magical) topics in AI—Deep Learning. known as the weight, and each node has a value known
as the bias (see Figure 2). Initially, weights and biases are
randomly assigned to each connection and node. The key
Wei-Meng Lee What is Deep Learning? role of a neural network is to find the ideal set of weights
weimenglee@learn2develop.net If you’re familiar with machine learning and its associated and biases that best describes the relationships between
http://www.learn2develop.net algorithms (linear regression, logistic regression, Support the input and the output.
@weimenglee Vector Machine, K-Nearest Neighbors, K-Means, etc.), you’re
no stranger to the various steps needed to feed your data to
Wei-Meng Lee is a technolo-
gist and founder of Devel- the algorithms in order to train the model to perform predic-
oper Learning Solutions tions. Predictably, you need to perform the following steps: The key role of a neural network
(www.learn2develop.net), is to find the ideal set of weights
a technology company spe- • Data cleansing
cializing in hands-on train- • Data visualization and biases that best describes
• Features selection
ing on the latest technolo-
• Splitting dataset for training and testing
the relationships between
gies. Wei-Meng has many
years of training experiences • Evaluating different algorithms the input and the output.
and his training courses
place special emphasis In short, machine learning requires feature engineering.
on the learning-by-doing You need to structure your data first and then follow a stan-
approach. His hands-on dard procedure to solve the problem—break the problem What does this mean? Let’s take a look at an example. Us-
approach to learning into smaller parts and then solve each of them and combine ing the classic example of the Titanic dataset, consider a
programming makes them to get the required result. specific row where the age is 18, cabin class is first class (1),
understanding the subject and number of siblings is 1. This will serve as the input for
much easier than read- Wouldn’t it be great if there were a much easier way to train the neural network. This particular passenger didn’t survive
ing books, tutorials, and a model such that you just need to feed your data to an the disaster, and so the output is 0. When the neural net-
documentation. His name algorithm and it auto-magically establishes the relationship work is trained using the Titanic dataset, the neural network
regularly appears in online
between your input and output? Turns out that there’s really has a set of weights and biases that allow you to predict the
and print publications such
such a magical algorithm: that’s deep learning. probability of survival of another new passenger. How the
as DevX.com, MobiForge.
com, and CODE Magazine.
network is trained is the magic behind deep learning, and
Before I dive into how deep learning works, it’s essential to de- this is what I’ll dive deeper into later in this article.
fine what deep learning is. Deep learning is a machine learning
method that takes an input X and predicts an output Y. It does With the network trained (with the weights and biases derived),
this by taking a given set of inputs and their associated outputs, you can supply new passenger details through the input layer.
and it tries to minimize the difference between the prediction Starting with the inputs at the input layer, the value of each
and expected output. In short, deep learning learns the rela- node is multiplied with the weight for the particular connection
tionships between the input and output. Once the learning is and added to the biases at the next node. Figure 3 summarizes
done, it will be able to predict new output based on your input. the formula for calculating the value at the next node.

Understanding Neural Networks


To understand deep learning, you need to understand Arti- The Activation Function is also
ficial Neural Networks (ANN).
known as the step function.
Figure 1 shows a neural network consisting of the following
components:
Activation Function
• Input layer: Your data goes into the neural network After the value of the node is calculated, the value is passed
through the input layer. into a function known as the activation function. The role
• Hidden/neural layers: The hidden layers contain neu- of an activation function is to help you normalize (control)
rons (also known as nodes). Typically, in a neural net- the output of a neural network. Let’s see how an activation
work, there are one or more hidden layers. function works before I discuss why you need one.

44 Introduction to Deep Learning codemag.com


Figure 1: A neural network with its various layers and nodes in each layer

Figure 2: Initially, weights and biases are randomly assigned to each connection and node in the neural network.

There are a few types of activation functions; here are some


common types:

• Binary step activation function


• Linear activation functions
• Non-linear activation functions

Binary Step Function


The output of the binary step activation function looks like
Figure 4.

A binary activation function is a threshold-based activa-


tion function—if the input value is above or below a certain
threshold, it outputs a value of 1 or 0, respectively.

An easy way to imagine the binary step function is to use


this analogy. Suppose you place your hand on the kettle. Figure 3: Calculating the immediate value of a neuron

codemag.com Introduction to Deep Learning 45


Your hands will be on the kettle as long as the temperature
on the kettle is below your tolerance threshold. The mo-
ment the water in the kettle starts to boil and reaches a
temperature that’s too hot for you to handle, you immedi-
ately remove your hands from the kettle. In this example,
the temperature of the kettle is the input and the placement
of your hand is the output.

Linear Activation Function


The output of the linear activation function is not limited to
any range. Figure 5 shows the graph for a linear function.

The linear activation function is of the form y = cx. The de-


rivative of this function is a constant: dy/dx = c and has no
Figure 4: The input and outputs of a binary step function relation to the input (x). When there’s an error in predic-
tion, you wouldn’t be able to understand how changes to x
affect the predicted output. A neural network with a linear
activation function is simply a linear regression model. It
has limited power and ability to handle complexity varying
parameters of input data. Linear activation function is usu-
ally used at the output layer, when you need to predict a
range of values.

A neural network with a linear


activation function is simply
a linear regression model.

Non-Linear Activation Function


Figure 5: The input and output of a Linear Activation function There are several non-linear activation functions. The Sig-
moid (logistic) activation function is an example of a
non-linear activation function. The output of the Sigmoid
function lies in (0,1).

The formula for the Sigmoid activation function is as shown


Figure 6: The formula for the in Figure 6.
Sigmoid Activation function
Figure 7 shows the graph of the Sigmoid activation func-
tion.

The Sigmoid activation function is useful for models where


you have to predict the probability as an output. It’s com-
monly used at the output layer to determine the probability
of a prediction. For example, if the neural network outputs
multiple answers (such as the detection of various objects
in an image), you can use the Sigmoid activation function to
Figure 7: The input and output of a Sigmoid Activation function calculate the probability of each prediction, such as:

• Dog; 0.8
• Cat: 0.4
• Guinea Pig: 0.1

Figure 8: The Softmax formula Note that the sum of the three outputs above need not be
equal to one. In cases where your neural network outputs a
probability distribution (such as the probabilities of a per-
son being male, female, or unknown), you need to use a
Softmax activation function. Figure 8 shows the formula for
the Softmax function.

Figure 9 shows the graph of the Softmax activation function


taking in an input list of [0.4, 3.0, 2.2]. The value on the
y-axis is the output of the Softmax function: [0.04874866
Figure 9: The input and output of a Softmax Step function 0.65633915 0.29491219].

46 Introduction to Deep Learning codemag.com


When used on the example of predicting the gender of a
person in a picture, this translates to:

• Male: 0.04874866
• Female: 0.65633915
• Unknown: 0.29491219

Note that all probabilities add up to 1.

Another commonly used activation function is known as the


Hyperbolic Tangent activation function (commonly written
as Tanh). Figure 10 shows the Tanh activation function com-
pared to the Sigmoid activation function.

Observe that the output of the Tanh activation function lies Figure 10: The input and output of a Tanh activation
in (-1,1). The Tanh activation function works very much like function, compared with the Sigmoid activation function
the logistic Sigmoid activation function. Its key advantage
is that the negative input will be mapped strongly negative
and the zero inputs will be mapped near zero. Tanh is mainly
used for two-class classifications.

Besides the Tanh and Sigmoid activation functions, another


non-linear activation function that’s most used in the world
of machine learning at this moment is known as the Recti-
fied Linear Unit (or commonly known as ReLU).

Figure 11 shows what the ReLU activation function looks


like. It’s half rectified (from the bottom). R(x) is zero when
X is less than zero and R(x) is equal to X when X is above or
equal to zero. Observe that its output lies in [0, infinity).

One issue with ReLU is that any negative input given to the Figure 11: The input and output of a ReLU activation function
ReLU activation function turns the value into zero immediately
in the graph, which, in turn, affects the resulting graph by not
mapping the negative values appropriately. This decreases the
ability of the model to fit or train from the data properly.

To solve the dying ReLU problem, researchers came out with


a novel solution named Leaky ReLU. Figure 12 shows what
the Leaky ReLU activation looks like.

The formula for Leaky ReLU is:

LR(x) = max(x*a, x)

As you can see from the figure, the “leak” on the left chart
of the graph helps to increase the range of the ReLU func- Figure 13: The formula for
tion. Usually, the value of a is 0.01 or so. When a is not calculating Mean Squared
0.01, it’s called Randomized ReLU. The range of the Leaky Figure 12: The input and output of a Leaky ReLU activation function Error (MSE)
ReLU is (-infinity to infinity).

Loss Functions
In the previous section, you learned that after the value of
each node is calculated, it’s passed to an activation func-
tion, whose output is then passed to the next neuron for
calculation.

After the neural network passes its inputs all the way to its
outputs, the network evaluates how good its prediction was
(relative to the expected output) through something called
a loss function (also known as cost function). The Mean
Squared Error (MSE), is one such function.

Figure 13 shows the formula for calculating the MSE, where


Yi is the expected output, ^y I is the predicted output, and n
is the number of samples. Figure 14: Calculating the loss using cross entropy

codemag.com Introduction to Deep Learning 47


When training a neural network, aim to minimize the loss
function so as to minimize the errors of your model.

Cross Entropy
Besides MSE (which is often used for regression), you can
also use the cross-entropy loss function. The cross-entropy
loss (also known as log loss) function is shown in Figure 14.

Cross entropy can be applied to classification problems.


In particular, if you’re solving a:

• Binary classification problem, use binary cross en-


tropy
• Multi-class classification problem, use categorical
cross entropy

The formula for binary cross entropy is:

−(ylog(p)+(1−y)log(1−p))

Figure 15: Loss value: the difference between the In this example, y is the actual output and p is the predicted
predicted target and the actual target probability.

Cross-entropy loss increases when the predicted probability


deviates from the actual label. For example, if the actual
result is 1 and the predicted probability is 0.01, the log loss
is much higher than if the predicted probability is closer to
1. A perfect model would have a log loss of 0.

For categorical cross entropy, the formula is:

M
−∑ yo,clog(po,c)
c=1

In this example, M is the number of classes, yo,c is the re-


sult (0 or 1) if class label c is the correct classification for
Figure 16: Understanding the significance of the derivative observation o, po,c is the predicted probability observation
of a function o of class c. Categorical cross entropy is also known as the
softmax loss.

Backpropagation Using Optimizer


As described in the previous section, using a loss function al-
lows you to know how much your prediction has deviated from
the expected output. The aim is to minimize the value of the
loss function. So how do you do that? You need to traverse back
up the neural network to update the weights and biases so that
your new predicted output will result in a lower loss. But with
so many weights and biases, how do you efficiently adjust the
weights and biases so that you can achieve minimal loss?

You can do this via a technique known as backpropagation.


Using backpropagation, the network backtracks through all
its layers to update the weights and biases of every node in
the opposite direction of the loss function. Each iteration of
back propagation should result in a smaller loss function than
before. The continuous updates of the weights and biases of
the network should ultimately turn it into a precise model that
maps the relationship between inputs and expected outputs.

In the next section, I’ll walk you through how backpropaga-


tion works by using a simple example.

Expressing the Loss Function as a Function of Weights


Consider Figure 15. Here, you have an input represented as
Figure 17: A simple neural network an input vector (x). The input vector is multiplied with the

48 Introduction to Deep Learning codemag.com


weights (W) to produce the computed target (y_pred). The • The derivative completely describes how f(W) evolves
expected target is y. as you change W.

The loss value is the difference between the computed tar- Hence, you can conclude that for a particular value of W, the
get and the target. The loss value can be expressed as a derivative of the loss function f(W) will tell how much the
function of W, like this: loss value is increasing or decreasing. More importantly, if
you want to reduce the value of f(W), you just need to move
Loss_value = f(W) W a little in the opposite direction from its derivative. You
will see the importance of this statement in a short while.
Your aim is to reduce the loss value, i.e., reduce the value
of f(W).

Understanding Derivatives (Gradients)


Before you understand how backpropagation works, it’s
useful to revisit some basic calculus. Figure 16 shows the
loss function f(W) plotted as a curve.

If you want to reduce the value of


the loss function f(W), you just need
to move W a little in the opposite
direction from its derivative.

The slope (gradient) on any particular point on the curve


is the derivative of the function: df(W)/dW. In the figure,
a is the gradient of a point on the slope. You can observe
the following:

• If a is positive (+), this means a small increase in W


will result in an increase of f(W).
• If a is negative (-), this means a small increase in W
will result in a decrease of f(W).
• The absolute value of a tells you the magnitude of change. Figure 18: Setting the initial values for the weights and nodes

Figure 19: Calculating the derivatives for the various nodes

codemag.com Introduction to Deep Learning 49


A Walkthrough of Gradient Descent dŷ/dw1 = x1
To understand how backpropagation works, let’s walk dŷ/dw2 = x2
through an example using a popular backpropagation algo-
rithm: gradient descent. So dL/dy^ represents the rate of change of L with respect to
^y . Likewise, dy^/dw1 represents the rate of change of ^y with
First, assume that you have a dataset with two inputs, x1 respect to w1, and so on. You can now plug in the formulas
and x2, and an output y. Suppose you have a very simple to the network, as shown in Figure 19.
neural network, as shown in Figure 17. Note that, for sim-
plicity, I have omitted the biases in this illustration. Based on the formulas, you’re now ready to update the
weights based on the following formula:
Let’s try to plug in the first row of the dataset. Suppose you
have inputs x1 = 4, x2 = 5, and y = 6. For the initial iteration w1' = w1 - η(dL/dw1)
of the training process, you initialize the weights with some
random values, say w1 = -0.234 and w2 = 0.675. You can now Where:
start to calculate the value of ^y as well as the loss value
(see Figure 18). • w1’ is the value of w1 after the update
• w1 is the current value of w1
• η is the learning rate = 0.05; usually a value from 0
to 1
Gradient descent is known as • dL/dw1 is the rate of change of L with respect to w1
an optimizer algorithm.
Observe the minus sign in the equation. Remember, earlier
on I mentioned that if you want to reduce the value of the
loss function (f(W)), you just need to move W a little in the
The loss value of the first row is 12.680721. The aim is to opposite direction from its derivative.
modify the weights so that in the next iteration, the loss
value can be reduced. How much should you change the To find dL/dw1, it can be expressed as:
weights? Before you do that, let’s look at some formulas.
You know the following: dL/dw1 = dL/dŷ * dŷ/dw1

ŷ = x1w1 + x2w2 And from the previous equations, you know that:
L = (ŷ-y)2
= ŷ2 - 2yŷ + y2 dL/dŷ = 2(ŷ - y)
dŷ/dw1 = x1
Let’s take the partial differentials of the above formulas
with respect to the various variables: Hence, dL/dw1 can be expressed in terms of ^y , y, and x1,
like this:
dL/dŷ = 2ŷ - 2y
= 2(ŷ - y) dL/dw1 = 2(ŷ - y) * x1

Figure 20: Updating the


weights after the first epoch Figure 21: Summary of the use of the activation function, loss function, and the optimizer

50 Introduction to Deep Learning codemag.com


With x1 = 4, w1 = -0.234, y = 6, η = 0.05, ^y = 2.439 (see
Figure 18):

w1' = w1 - η(dL/dw1)
= -0.234 – 0.05(2(2.439 - 6) * 4)
= 1.1904

Similarly, for w2’, the formula is:

w2' = w2 - η(dL/dw2)
dL/dw2 = dL/dŷ * dŷ/dw2
dL/dŷ = 2(ŷ - y)
dŷ/dw2 = x2

With x2 = 5, w2 = 0.675, y = 6, η = 0.05, ^y = 2.439 (see


Figure 18):

w2' = w2 - η(dL/dw2)
= 0.675 – 0.05(2(2.439 - 6) * 5)
= 2.4555

You can now update the value for w1 and w2 (see Figure 20).

That’s the end of the first row in your dataset. You need to re-
peat the steps described above for the rest of the rows in your
dataset. After going through all the rows in your dataset, that’s
one epoch completed. In order for the loss to converge, you
need to perform multiple epochs to update the weights and
biases in each iteration. At the end of all the epochs, you’ll be
able to derive the value of w1 and w2, which allows you to take
on new input to predict the new output.
Figure 22: Displaying the first two images in
Google has an online visual demo on how backpropagation works. the training set
If you’re interested in how backpropagation works for multi-layer
neural network, check it out at: https://google-developers.ap-
pspot.com/machine-learning/crash-course/backprop-scroll/. Smaller batch size requires less memory, because you’re
training the network using fewer samples at any one time.
At this juncture, it’s useful to refer to Figure 21, which In addition, it’s been found that a smaller batch size pro-
shows how the activation function, loss function, and the duces a more accurate model compared to larger batch size.
optimizer work to train the neural network. Using a larger batch size can be faster compared to a small-
er batch size.

Batch Size and Epoch The number of epochs determines how many times the
In deep learning, the batch size is the number of samples learning algorithm walks through all the rows in the en-
processed before the weights and biases in the neural net- tire dataset. An epoch comprises of one or more batches.
work are updated. In the example shown in the previous In real life, you often have to run your training over a large
section, the batch size is 1. If the batch size is 5, this means number of epochs in order for the errors to be sufficiently
the weights and biases will only be updated after sampling minimized. It’s not uncommon to see epochs of 500, 1000,
five rows. The weights will be updated at the end of the fifth or more.
row, based on the average of the five gradients obtained in
each iteration. For example, for the first weight, you take Finally, let’s see an example to fully understand the rela-
the average of dL/dw1 obtained for each row. Then, using tionships between batch size and epochs. Suppose you have
this average, you update the weight according to the for- a dataset of 10,000 rows. Given a batch size of 5, there will
mula described earlier. be a total of 10,000/5, or 2000 batches. This means that the
weights and biases will be updated 2000 times in a single
A dataset can be divided into one or more batches. The fol- epoch. With 1000 epochs, the weights and biases will be
lowing learning algorithms are named according to the size updated a total of 2000 x 1000, or 2 million times.
of each batch:

• Batch gradient descent: Batch size is the same as the TensorFlow, Keras, and Deep Learning
size of the dataset Developers who want to get started with deep learning can
• Stochastic gradient descent: Batch size is 1 (i.e., the make use of TensorFlow, an open source library by Google
weights and biases are updated at the end of each row) that helps you create and train deep learning neural net-
• Mini-batch gradient descent: The batch size is more works. TensorFlow has a steep learning curve and may
than 1 and less than the size of the dataset. Popular not be easy to work with if you just want to get started
sizes are 32, 64, and 128. with deep learning. To make TensorFlow more accessible, a

codemag.com Introduction to Deep Learning 51


Google AI researcher named François Chollet created Keras, import mnist
an open-source neural-network library written in Python. from tensorflow.keras.models \
Keras runs on top of TensorFlow and makes creating your import Sequential
deep learning model much easier and faster. from tensorflow.keras.layers \
import Dense, Activation
Using Keras to Recognize Handwritten Digits from tensorflow.keras.optimizers \
With the theory out of the way, it’s now time to look at some import SGD
code and work on building your first deep neural network. from tensorflow.keras.utils \
For this, you’ll need to install Anaconda. You’ll make use of import to_categorical
Jupyter Notebook. from tensorflow.keras.models \
import Sequential
Installing TensorFlow and Keras
The first step after launching Jupyter Notebook is to install Getting the Dataset
TensorFlow and Keras. In the first cell of Jupyter Notebook, For this example, you’re going to use the MNIST (Modified
type the following statement: National Institute of Standards and Technology) dataset,
which is a large database of handwritten digits that’s com-
!pip install tensorflow monly used for training various image processing systems.
The following statements loads the MNIST dataset and
The above statement installs TensorFlow and Keras on your prints out the shape of the training and testing dataset:
computer.
(X_train, y_train), (X_test, y_test) = \
Import the Libraries mnist.load_data()
Next, import all of the libraries that you’re going to need,
including NumPy, matplotlib (for charting), as well as the print(X_train.shape) # (60000, 28, 28)
various classes in Keras: print(y_train.shape) # (60000,)
print(X_test.shape) # (10000, 28, 28)
import numpy as np print(y_test.shape) # (10000,)
import matplotlib.pyplot as plt
As you can see, there are 60,000 records for the training set
from tensorflow.keras.datasets \ and 10,000 records for the testing dataset. Each handwrit-
ten digit is stored as a 28x28 two-dimensional array. If you
want to see how the digits are stored, you can try printing
out the first one, like this:

print(X_train[0])

You’ll see a two-dimensional array containing a series of


values from 0 to 255. To see what digit is represented by
this array, print out its label:

print(y_train[0]) # 5

Visualizing the Dataset


A better way to visualize the dataset is to plot it out us-
ing matplotlib. The following statements print out the first
two digits in the training dataset (see Figure 22 for the
output):

# show the first 2 images in the


# training set
for i in range(2):
plt.figure()
plt.imshow(X_train[i])
plt.colorbar()
plt.grid(True)
plt.xlabel(y_train[i])
plt.show()

Reshaping the Data


For training your neural network, you need to reshape (flat-
ten) the 28x28 two-dimensional array into a single dimen-
sion. The following statements accomplish that:

NEW_SHAPE = 784 # 28x28

Figure 23: The neural network you’ll build in this article to train to recognize handwritten digits X_train = X_train.reshape(60000, NEW_SHAPE)

52 Introduction to Deep Learning codemag.com


Listing 1: Building the neural network using Keras
model = Sequential() # uses ReLu
model.add(Dense(128, activation=’relu’))
# hidden layer 1; takes in input arrays of
# shape (*,784) and output arrays of shape (*, 128) # output layer; takes in (*,128) and outputs (*,10)
model.add(Dense(128, input_shape=(NEW_SHAPE,))) model.add(Dense(CLASSES))
# uses the ReLu activation function model.add(Activation(‘softmax’))
model.add(Activation(‘relu’))
‘’’
# hidden layer 2; no need to specify input (it takes The above 2 lines can also be written as
# from the previous layer); takes in input arrays of model.add(Dense(CLASSES, activation=’softmax’))
# shape (*,128) and output arrays of shape (*, 128); ‘’’

X_train = X_train.astype(‘float32’) print(y_train[1])


print(X_train.shape) # (60000, 784) # 0

X_test = X_test.reshape(10000, NEW_SHAPE) print(Y_train[1])


X_test = X_test.astype(‘float32’) # [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
print(X_test.shape) # (10000, 784)
Building the Model
X_train was initially 60,000 rows of 28x28 values, but after With the dataset reshaped and encoded, you’re now ready
reshaping, it will now be 60,000 x 784. Likewise for x_test— to build the neural network. Figure 23 shows the neural
after reshaping, it will be 10,000 x 784. network that you’ll build.

Normalizing the Data From the figure, observe that:


You also need to convert the values of the images from a
range of 0 to 255 to a new range of 0 to 1. The following • There’s an input layer of 784 nodes. This corresponds to
statements do just that: the 28x28 pixels of each image. Each of the images is flat-
tened, so each image corresponds to 784 pixels (28x28).
X_train /= 255 • Each of the 128 nodes in the first hidden layer takes in
X_test /= 255 784 inputs from the input layer and then calculates 128
outputs, which are then passed to the next hidden layer.
One-Hot Encoding • Each of the 128 nodes in the second hidden layer re-
For the label of the dataset, you need to perform one-hot ceives the 128 inputs from the previous hidden layer
encoding. Essentially, one-hot encoding translates the val- and calculates 10 outputs, which are then passed to
ue of the label into an array of 1s and 0s, with a single 1 the last layer (the output layer).
representing the value and the rest filled with 0s. The best • Calculated using the Softmax activation function,
way to understand one-hot encoding is an example, such as each neuron in the output layer contains a probability
the value 5 one-hot encoded as: that corresponds to the digit that is currently trained/
predicted.
[0,0,0,0,0,1,0,0,0,0]
With the model designed, it’s now time to code it using
The value 8 is represented as: Keras. Listing 1 shows the model written using Keras.

[0,0,0,0,0,0,0,0,1,0] With the model created in code, it’s always useful to print
out the model and verify its correctness. You can do this us-
Make sense now? The following statements performs a one- ing the summary() method of the model object:
hot encoding for the labels stored in Y_train and Y_test:
model.summary()
CLASSES = 10 # number of outputs =
# number of digits You’ll see the various layers of your model, as shown in Fig-
ure 24. Notice that, in this case, you have three activation
# convert class vectors to binary class functions: one each after the two hidden layers where you
# matrices - one-hot encoding use the ReLU activation function, and the third one is at the
Y_train = to_categorical(y_train, CLASSES) output layer, where you use the softmax function to provide
Y_test = to_categorical(y_test, CLASSES) the probability of predicting each digit.

# label for first row in training set Compiling the Model


print(y_train[0]) # 5 With the model created, you next need to compile it by
specifying the loss function you want to use for this model
# label (one-hot encoded) for first row and the optimizer you want to use for backpropagation:
# in training set
print(Y_train[0]) model.compile(
# [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.] loss=’categorical_crossentropy’,
optimizer=SGD(),
# second row label metrics=[‘accuracy’])

codemag.com Introduction to Deep Learning 53


For the example, I used the categorical cross entropy as Training the Model
the loss function, and the Stochastic Gradient Descent You’re now ready to train the model:
(SGD) as the optimizer for backpropagation. For the metric
to measure the effectiveness of our model, I used accuracy EPOCH = 100
as the metric. BATCH_SIZE = 64
VERBOSE = 1
VALIDATION_SPLIT = 0.2

history = model.fit(
X_train, Y_train,
batch_size=BATCH_SIZE,
epochs=EPOCH,
verbose=VERBOSE,
validation_split=VALIDATION_SPLIT)

You specify a batch size of 64 and a validation split of 0.2


(20%). This means that when training the model with the
specified dataset, 80% of the training dataset will be used
for testing, while the rest (20%) will be used to verify the
accuracy of the model. The fit() function returns a History
object. The object stores a record of training loss values and
metric values at successive epochs, as well as validation loss
values and validation metrics values.

As the model trains, you’ll see the output, as shown in Figure 25.
Figure 24: Printing out the summary of the model you’ve created
As the training goes through each epoch, it prints the train-
ing accuracy and the validation accuracy (as well as the
training and validation loss). Training accuracy is obtained
by applying the model on the training data.

At the early stage of training, the training accuracy should


fall below the validation accuracy. After a number of ep-
ochs, the training accuracy will start to rise above the vali-
dation accuracy. This means that your model is fitting the
training set better, but losing its ability to predict new data,
which means that your model is starting to overfit. At this
point, it’s useful to stop the training.

Evaluating the Model


Once the training is done, you can evaluate the model by
passing in the testing dataset to the trained model:

score = model.evaluate(X_test, Y_test,


verbose=VERBOSE)
print(“\nTest score:”, score[0])
print(‘Test accuracy:’, score[1])
Figure 25: Examining the output during the training phase
A bunch of text will be displayed, but at the end of the out-
put, you’ll see the most important information:

Test score: 0.08266904325991636


Test accuracy: 0.9756

An accuracy of 97.56 certainly looks good!

Plotting the Training Accuracy and Validation


Accuracy Chart
Using the History object returned by the fit() function, let’s
now plot a chart to show the training and validation accura-
cies of the model during the training phase:

# list all data in history


print(history.history.keys())
Figure 26: The chart showing the training accuracy vs. plt.plot(history.history[‘accuracy’])
validation accuracy

54 Introduction to Deep Learning codemag.com


plt.plot(history.history[‘val_accuracy’]) [[7.0899937e-08 8.5124242e-08 1.1331436e-08
plt.title(‘model accuracy’) 9.9979192e-01 1.9511590e-13 2.1899252e-06
plt.ylabel(‘accuracy’) 4.0693807e-13 3.2966765e-11 1.3524551e-04
plt.xlabel(‘epoch’) 7.0466805e-05]]
plt.legend([‘train’, ‘val’],
loc=’upper left’) The first element in the result array shows the probability
plt.show() of the test digit being 0, and the second element shows
the probability of the test digit being 1, and so on. You can
Figure 26 shows the chart plotted. observe that the fourth element (index 3) has the largest
probability among all the other probabilities. Thus the pre-
As you can see, the training accuracy out-performs valida- dicted number is 3 (remember the digit starts from 0).
tion accuracy at around 17 or 18 epochs. The ideal epoch
would be around 17 or 18. An easier way to know the predicted digit (class) is to use
the predict_classes() function, which directly returns the
Plotting the Training Loss and Validation Loss Chart digit predicted:
You can also plot a chart showing the training loss and vali-
dation loss during the training phase (see Figure 27 for the print(model.predict_classes(x))
chart): # [3]

plt.plot(history.history[‘loss’]) You can compare the result with the original one-hot en-
plt.plot(history.history[‘val_loss’]) coded value of the row:
plt.title(‘model loss’)
plt.ylabel(‘loss’) # see the original value
plt.xlabel(‘epoch’) print(Y_test[index])
plt.legend([‘train’, ‘test’], # [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
loc=’upper left’)
plt.show() Saving the Trained Model
Once your model is trained, you can save it to disk so that
Performing Predictions the next time you want to make a prediction, you don’t have
Finally, you can now make some predictions using the model to go through the entire training process again. Although
that you’ve trained. To do so, let’s select a particular row from this current example doesn’t take long to train, in real life,
the X_test dataset (say, index 90). In order to perform the
prediction, you need to reshape the test item into an array of
shapes (1,784). It’s also useful to visually inspect the test row
before performing the prediction:

index = 90

# shape of X_test
print(X_test.shape)
# (10000, 784)

# shape of the first item in X_test


print(X_test[index].shape)
# (784,)

# in order to do prediction, you need


# to send in a 2-d array of shape (,784) Figure 27: The chart showing the training loss vs.
x = X_test[index].reshape(-1,784) validation loss
print(x.shape)
# (1,784)

# show the number


plt.imshow(X_test[index].reshape(28,28),
interpolation=’none’)
plt.title(“Digit: {}”.format(y_test[index]))

Figure 28 shows the digit to be predicted as well as its real value.

You can now perform the prediction using the predict() func-
tion:

# you can do the prediction now


print(model.predict(x))

The above statement yields the following result: Figure 28: Visualizing the number to be predicted

codemag.com Introduction to Deep Learning 55


there are models that will take days, if not weeks, to train. # creates a HDF5 file 'trained_model.h5'
Therefore, it’s important to be able to save the trained mod- model.save(‘trained_model.h5’)
el to disk for use later on. The following statements save the
trained model as a HDF5 file: Loading the Saved Model
Once the model is saved, you want to verify that it’s saved
properly by loading it back from disk. The following state-
Listing 2: Converting the TensorFlow Model to TensorFlow Lite ments load the saved model:
# tensorflow 1.x
import tensorflow.compat.v1 as tf from tensorflow.keras.models \
import load_model
# load the trained model
converter = # returns a compiled model identical to
tf.lite.TFLiteConverter.from_keras_model_file(
# the previous one
‘trained_model.h5’)
model = load_model(‘trained_model.h5’)
# convert it to tensorflow lite
tflite_model = converter.convert() Perform a prediction using the same row that you tested
earlier and you should see the same result:
# write the tensorflow lite model to disk
open(“trained_model.tflite”,
print(model.predict_classes(x))
“wb”).write(tflite_model)
# [3]

Converting to TensorFlow Lite


Although TensorFlow allow you to train deep learning neural
networks as well as make inferences (predictions) on your
computer, it’s useful to be able to make inferences on the
edge. This is the use of TensorFlow Lite. TensorFlow Lite is a
light-weight version of TensorFlow, designed specifically for
inferencing on mobile devices.

For the model that you’ve trained, you can convert it into
TensorFlow Lite using the TFLiteConverter class, as shown
in the statements in Listing 2.

Saving the model as TensorFlow Lite allows your model to be


used in mobile applications, such as iOS and Android apps.
After the conversion is done, you’ll see a number displayed,
like this:

474736

This is the size of the TensorFlow Lite model saved on disk,


in bytes. So the generated TensorFlow Lite model is about
475 kilobytes.

Using TensorFlow on Mobile Apps:


TensorFlow Lite
Now that you’re able to save your model in TensorFlow Lite,
let’s do something interesting. Instead of using the test da-
taset for verifying your model, you’re going to handwrite
your own digits and let the model perform the prediction on
a mobile app. For this, you’re going to use Flutter so that
you can create the application that can run on both Android
and iOS devices.

Creating the Project


I’m going to assume that you have installed Flutter on your
computer. If not, check out my earlier Flutter article in CODE
Magazine (https://www.codemag.com/Article/1909091/
Cross-Platform-Mobile-Development-Using-Flutter).

To create a new application using Flutter, type the following


commands in Terminal:

$ flutter create recognizer


Figure 29: Trying the handwriting app on the iPhone Simulator $ cd recognizer

56 Introduction to Deep Learning codemag.com


Capturing the User’s Handwriting     sdk: flutter
To allow users to handwrite the digit, use a Flutter package   flutter_signature_pad: ^2.0.0+1
called flutter_signature_pad. This package allows users to   image:
sign with the finger and export the result as an image.
Add the statements shown in bold in Listing 3 to the main.
Add the following statements in bold to the pubspec.yaml dart file in the lib folder of your Flutter project.
file:
Let’s give the app a spin and see how you can scribble on the
dependencies: signature pad. In Terminal, type the following command to
  flutter: launch the app on the iPhone Simulator:

Listing 3: The statements in bold allow you to draw on your mobile app using your finger
import 'package:flutter/material.dart'; child: Signature(
color: color,
import ‘dart:ui’ as ui; key: _sign,
import ‘package:flutter_signature_pad/ onSign: () {
flutter_signature_pad.dart’; final sign =
import ‘package:image/image.dart’ as img; _sign.currentState;
},
void main() => runApp(MyApp()); strokeWidth: strokeWidth,
),
class MyApp extends StatelessWidget { ),
@override MaterialButton(
Widget build(BuildContext context) { color: Colors.yellow,
return MaterialApp( child: Text(“Recognize”),
title: 'Flutter Demo', onPressed: () async {
theme: ThemeData( final sign = _sign.currentState;
primarySwatch: Colors.blue,
), // get the signature data
home: MyHomePage(title: final sigImage =
'Flutter Demo Home Page'), await sign.getData();
);
} // convert to png format
} var data = await
sigImage.toByteData(format:
class MyHomePage extends StatefulWidget { ui.ImageByteFormat.png);
MyHomePage({Key key, this.title}) :
super(key: key); final buffer = data.buffer;
final String title; var imageBytes =
buffer.asUint8List(
@override data.offsetInBytes,
_MyHomePageState createState() => data.lengthInBytes);
_MyHomePageState();
} img.Image image = img.decodePng(
imageBytes);
class _MyHomePageState extends State<MyHomePage> {
// draw the signature in red, with width 15 // resize the image
var color = Colors.red; image = img.copyResize(
var strokeWidth = 15.0; image, width:28);
final _sign = GlobalKey<SignatureState>();
String result = “”; // clear signature pad
sign.clear();
BoxDecoration myBoxDecoration() { },
return BoxDecoration( ),
border: Border.all(), MaterialButton(
); child: Text(“Clear”),
} color: Colors.lime,
onPressed: () {
@override final sign = _sign.currentState;
Widget build(BuildContext context) { sign.clear();
return Scaffold( setState(() {
body: result = “”;
Center( });
child: Column( debugPrint(“cleared”);
mainAxisAlignment: },
MainAxisAlignment.center, ),
children: <Widget>[ Text(‘$result’,
Container( style: TextStyle(
margin: const EdgeInsets.all(10.0), fontWeight: FontWeight.bold,
width: 200.0, fontSize: 20,),
height: 200.0, textDirection: TextDirection.ltr,),
decoration: BoxDecoration( ]
border: Border.all(width: 3.0), ),
borderRadius: BorderRadius.all( ),
Radius.circular(5.0) );
), }
), }

codemag.com Introduction to Deep Learning 57


$ open -a simulator Next, add the trained_model.tflite file that you have con-
$ flutter run -d all verted earlier into the model folder. To bundle the both the
trained_model.tflite and trained_model.txt files with your
You can now scribble on the signature pad and tap Clear to Flutter app, add the following statements in bold to the
restart (see Figure 29). pubspec.yaml file:

Using TensorFlow Lite dependencies:


Now that you can scribble on the app, let’s use the TensorFlow   flutter:
Lite model to predict the digit that you’ve scribbled. In the     sdk: flutter
project folder, add a new folder named model (see Figure 30):   flutter_signature_pad: ^2.0.0+1
  image:
Create a plain text file named trained_model.txt with the   tflite: ^1.0.4
following contents and save it to the model folder:
...
Figure 30: Adding a new Zero ...
model folder to the Flutter One
project Two flutter:
Three   assets:
Four    - model/trained_model.tflite
Five    - model/trained_model.txt
Six
Seven Add the statements in bold from Listing 4 to the main.dart
Eight file. Use the Tflite.runModelOnBinary() function is used for
Nine image classification (refer to https://pub.dev/documenta-
tion/tflite/latest/ for more examples).
This file contains the labels for the predictions. If the predic-
tion is 0, it will look for the first line in the file and return
“Zero”, and so on. Of course, you can replace “Zero” with any
value you want, such as 0, or any value of your preference. The tflite package is a Flutter plug-
in for accessing TensorFlow Lite API.
It supports image classification,
object detection (SSD and YOLO),
Pix2Pix and Deeplab, and PoseNet
on both iOS and Android.

Figure 31: The target for the iOS project must be set to at One possible result of the Tflite.runModelOnBinary() func-
least iOS 12.0. tion might look like this (formatted for clarity):

Figure 32: Setting the correct value for the “Compile Sources As” setting in Xcode

58 Introduction to Deep Learning codemag.com


[ {
{ index: 2,
index: 10, label: Two,
label: Nine, confidence: 0.9919105172157288
confidence: 1.2579584121704102 }
}, ]
{
index: 3, You need to iterate through the result and find those items
label: Three, whose index value is from 0 to 9 (because you’re predict-
confidence: 0.6730967641398132 ing digits from 0 to 9), and get the one with the highest
}, confidence.

Listing 4: Loading the TensorFlow Lite model


import ‘dart:typed_data’; Float32List(1 * inputSize * inputSize * 1);
import ‘package:flutter/services.dart’; var buffer =
Float32List.view(convertedBytes.buffer);
import 'package:flutter/material.dart'; int pixelIndex = 0;
import 'dart:ui' as ui; for (var i = 0; i < inputSize; i++) {
import 'package:flutter_signature_pad/ for (var j = 0; j < inputSize; j++) {
flutter_signature_pad.dart'; var pixel = image.getPixel(j, i);
import 'package:image/image.dart' as img; buffer[pixelIndex++] =
import ‘package:tflite/tflite.dart’; (img.getRed(pixel)) / 255;
}
void main() => runApp(MyApp()); }
return convertedBytes.buffer.asUint8List();
... }

class _MyHomePageState extends @override


State<MyHomePage> { void initState() {
var color = Colors.red; super.initState();
var strokeWidth = 15.0; loadModel();
final _sign = GlobalKey<SignatureState>(); }
String result = "";
BoxDecoration myBoxDecoration() {
//---load the TensorFlow Lite model--- return BoxDecoration(
Future loadModel() async { border: Border.all(),
Tflite.close(); );
try { }
String res;
res = await Tflite.loadModel( @override
model: “model/trained_model.tflite”, Widget build(BuildContext context) {
labels: “model/trained_model.txt”); return Scaffold(
print(res); body:
} on PlatformException { Center(
print(‘Failed to load model.’); ...
print(PlatformException); MaterialButton(
} color: Colors.yellow,
} child: Text("Recognize"),
onPressed: () async {
Future recognizeImageBinary(var imageBytes) final sign = _sign.currentState;
async { ...
var recognitions = await // resize the image
Tflite.runModelOnBinary( image = img.copyResize(
binary: imageToByteListFloat32( image, width:28);
imageBytes, 28),
numResults: 9, // perform prediction
threshold: 0.8, recognizeImageBinary(image);
asynch: true
); // clear signature pad
print(recognitions); sign.clear();
double highestConfidence = 0; },
String predictedDigit = “Not Recognized”; ),
for (final i in recognitions) { MaterialButton(
if (i[‘index’] <10 && ...
i[‘confidence’] > highestConfidence) { ),
predictedDigit = i[‘label’]; Text('$result',
} style: TextStyle(
} fontWeight: FontWeight.bold,
setState(() { fontSize: 20,),
result = predictedDigit; textDirection: TextDirection.ltr, ),
}); ]
} ),
),
Uint8List imageToByteListFloat32( );
img.Image image, int inputSize) { }
// the model has an input shape of 1x28x28x1 }
var convertedBytes =

codemag.com Introduction to Deep Learning 59


Listing 5: Adding the statements to the build.gradle file
android {         versionName flutterVersionName
    compileSdkVersion 28         testInstrumentationRunner 
"android.support.test.runner.AndroidJUnitRunner"
    sourceSets {     }
        main.java.srcDirs += 'src/main/kotlin'
    }     buildTypes {
        release {
    lintOptions {             signingConfig signingConfigs.debug
        disable 'InvalidPackage'         }
    }     }
    aaptOptions {
    defaultConfig {         noCompress ‹tflite›
        applicationId "com.example.recognizer"         noCompress ‹lite›
        minSdkVersion 19     }
        targetSdkVersion 28 }
        versionCode flutterVersionCode.toInteger()

Learning Rate For iOS Also, go to the page Runner > Targets > Runner > Build
You need to modify the iOS component of the project before Settings, search for Compile Sources As, and change the
The learning rate is the you can run it. In the ios folder of the project, open the value to Objective-C++ (see Figure 32).
amount that the weights Runner.xcworkspace file in Xcode.
are updated during training. For Android
Learning rate is also known Change the Target to iOS 12.0 (see Figure 31): For the Android component of your Flutter app, add the
as the step size. The learning statements in bold (see Listing 5) to the build.gradle file
rate is a positive value (from
in the android/app folder.
0 to 1) that determines
the size of each step in the
gradient descent process.
Testing the Application
If the learning rate is too small, That’s it! You’re now ready to make a prediction on the digit
the gradient descent process that you are going to scribble on your mobile app. In Termi-
can be slow. If the learning nal, type the following command:
rate is too large, gradient
descent can overshoot the $ flutter run -d all
minimum and may fail to
converge, or even diverge. If you encounter an error involving cocoapods, type the fol-
lowing command in Terminal:

$ sudo gem install cocoapods

Scribble a digit and click on the Recognize button. You


should now be able to use the application to recognize your
handwritten text (see Figure 33).

Summary
Phew! In this article, I’ve covered a lot of ground on deep
learning. Although there’s no way a single article can dis-
cuss everything on this very complex topic, I hope I’ve given
you a clear idea of what deep learning is and what it can do.
Specifically, we have discussed:

• What deep learning is


• What activation functions are and why you need them
• What an optimizer is and how it helps to improve the
performance of your neural network
• How backpropagation works
• How to build a neural network using TensorFlow and Keras
• How to train a neural network
• How to save a trained neural network to disk and ex-
port it to TensorFlow Lite so that you can perform in-
ferencing on the edge (on a mobile device)
• How to build a Flutter application to perform hand-
writing recognition

Be sure to try out the examples. Have fun with deep learning!

Figure 33: The application is now able to recognize your  Wei-Meng Lee
handwritten digit! 

60 Introduction to Deep Learning codemag.com


KNOWLEDGE
IS POWER!

Sign up today for a free trial subscription at www.codemag.com/subscribe/magadoffer

codemag.com/magazine
832-717-4445 ext. 8 • info@codemag.com

codemag.com Title article 61


Tim Huckaby and
Talk to an RD Markus Egger
Tim and Markus talk computer vision, artificial intelligence (AI), politics, crime, and
The Microsoft Regional other things at the DevIntersection conference in Las Vegas, November 2019.
Director Program
The Regional Director Program, or RDs for short,
Machine learning, artificial intelligence, and computer vision are among the hottest
is a program that allows Microsoft to identify topics of the day, especially at a conference like DevIntersection that took place at
influential individuals in an effort to give the the MGM Grand hotel in Las Vegas. At this event, Microsoft Regional Director Tim
community-at-large access to these individuals, Huckaby and our own Markus Egger (publisher of CODE Magazine and also a Microsoft
and also to provide a point of communication
and feedback into Microsoft. Regional Directors Regional Director) sat down and had a discussion of these topics as well as worries
do NOT work for Microsoft (and they aren’t about AI features getting too powerful, privacy laws being problematic, the impact of
paid for being part of the RD program), but AI on politics, doing good in the world with facial recognition, using computer vision
they have a formal relationship with Microsoft
that provides them with great insights and for everyday business apps, and many more. Let’s eavesdrop on the discussion!
connections within Microsoft.

The Microsoft Regional Director website Markus: We run similar businesses. I run Markus: The CNN Magic Wall is one of the pieces
(https://rd.microsoft.com) defines the RD CODE Consulting, a custom app-dev, con- of software your company wrote that probably
program in the following words: sulting, and training company [in addition to pub- everybody has seen, even if they didn’t know you
lishing CODE Magazine]. guys wrote it. There’s another election coming
“The Regional Director Program provides Microsoft up. Are they still using the same tools?
leaders with the customer insights and real- Tim: Which is a rough business. And I run Inter-
world voices it needs to continue empowering Knowlogy, a 20-year-old custom app-dev com- Tim: No. Somebody else has done their most re-
developers and IT professionals with the world’s pany. And awesome company to work at. We have cent software. I don’t know how much I can say
most innovative and impactful tools, services, an amazing list of customers and really cool proj- about all this, but Microsoft was a heavy sponsor
and solutions. Established in 1993, the program ects. Just not the greatest company in the world of all that election stuff we did. We did the ana-
consists of 160 of the world’s top technology to own. It’s such a tough business because, you lytics for both parties. We go back three elections
visionaries chosen specifically for their proven know, there’s only one CNN. We don’t get reoccur- through both Obama elections. We provided a ton
cross-platform expertise, community leadership,
ring revenue from the Magic Wall [political analy- of data science to both parties on an even playing
and commitment to business results. You will
sis and visualization system seen on CNN in past field. We built the voting app for the Iowa caucus,
typically find Regional Directors keynoting at
top industry events, leading community groups
elections] that we built for CNN. And the other which is basically 22 voting apps in Xamarin. The
and local initiatives, running technology-focused tricky thing, and I’m sure it’s the case in your good people of Iowa could vote electronically for
companies, or consulting on and implementing business too, is that 98% of the work we do is the first time in United States history. But Micro-
the latest breakthrough within a multinational protected by NDA. We can’t put it on our website, soft—as you’ve seen—has become really gun-shy
corporation.” we can’t talk about it. You know, we’re building of being involved in politics, being involved in
software for software companies—Microsoft, In- controversial AI things. Microsoft and CNN got a
Regional Directors are expected to have deep tel, Apple, Google, you name it—and really high little sideways and we unfortunately were part of
technical understanding of many of the Microsoft tech, smaller companies too. But it’s so one off the byproduct of that. They [CNN] are using a less-
technologies. Not just that, but RDs are expected and so unique. These businesses we own will nev- er version of a Web-based client in this election.
to have an understanding of, and experience er be 10,000-person businesses. There’s just not Unless something weird happens last minute, and
with, competing technologies. RDs are also a market big enough for custom solutions. they say “we need InterKnowlogy to save the day
expected to go beyond technical expertise and again.” I hope they do. I mean, CNN is here [at
have considerable business expertise. Many RDs Markus: It’s a bummer. We’re at DevIntersection the DevIntersection conference we are at].
present at corporate events, advise governments here in Las Vegas and we both did presentations.
and NGOs, and many similar scenarios. I just finished one of my sessions, and there were Markus: Yes, they just did a keynote panel.
Feel free to contact any of the Regional Directors probably three different samples where I would have
to get access to an RD’s expertise and a well- liked to have shown the real-world thing. But I can’t, Tim: I was in that panel. George Howell [from
informed opinion that isn’t shaped or influenced because it’s under NDA and I can only create a small CNN, who was part of the panel] is such a talented
by having to go along with Microsoft’s marketing example similar to a real-world scenario instead. guy. Anyway, so, yeah, we do cool stuff at Inter-
speak. You can contact RDs to get advice and Knowlogy. That’s one part of my life. The other
opinions on your projects regarding technical Tim: Right. And I’ve been working with the Cus- part of my life is that in my infinite brilliance—
needs. You can contact them to help analyze tom Vision Team at Microsoft for a long time and and you know I say that facetiously because this
how technology will influence your business. they’re just such brilliant, awesome people, you was really a dumb move on my part—is that for
You can invite RDs to speak to your project know, life-saving type people and you just can’t the last three years, I’ve been working two full
stakeholders, board of directors, or corporate talk about what we’re doing or what they’re do- time jobs. There’s my role at InterKnowlogy as the
event. And you can contact your RD for many ing. So it’s fairly frustrating, in that respect. But I founder, chairman, and basically a strategy guy.
more scenarios. love InterKnowlogy. It’s been around for 20 years And there’s the lines of business that I love and
and we, we really do cool stuff. we should focus on. You know, it has a CEO and it

62 Talk to an RD: Tim Huckaby and Markus Egger codemag.com


has awesome technical people, but it needs me “bad guy” to look at our camera. The really bad privacy law in China doesn’t exist, right? Or in all
for lead generation. And it didn’t have me for lead guys, they wear hoodies and they look down and of Latin America, it doesn’t exist. And it is what
generation for the last few years because I was they’re good at not looking at surveillance cam- it is. Anyways, once you look, we can do a num-
serving as the CTO of a public company and that eras and stuff like that. But this sort of content ber of things. Obviously, we can do a facial rec-
is VSBLTY, which I founded. We spawned some IP, always gets them to look at the camera that is ognition against a bad guy database. And then
we pulled it out of InterKnowlogy, and we ran with tiny and in the digital screen. send an alert to an authority that says, “We are
a product based on computer vision and it’s now 87% confident that Joe Bad Guy is here at this
deployed world-wide and it’s got a security and Markus: Should we tell people this, by the way? location” and it’s, you know, “send the picture
a retail component to it. Our tagline is “The in- [laughs]. with it and blah, blah blah.” But in the creepy
tersection of marketing and security”. It looks for factor, where you’re going, it could also change
the bad guy and it does weapon detection. Tim: It’s up to you. You said we can edit if we the content based on what it sees. For instance,
need to. [laughs]. if someone walks in front of the digital sign and
Markus: Is looking for the bad guy the main thing she’s holding a Coke, and one of the advertis-
VSBLTY does or does the company produce all Markus: If you don’t mind people knowing this, ers behind the digital screen is Pepsi, the con-
kinds of computer vision software? then that’s fine. I guess the people who read tent may change to Beyoncé drinking Diet Pepsi.
CODE Magazine are all good people. I think we That’s wildly effective for a certain demographic.
Tim: We have enrolled for patents that I’m named can tell them. [winks] For the technology elite, they might not get
on, which is kind of cool. Some brilliant ideas by fooled by that. But there is a demographic that
me and some other folks. This is in the weeds Tim: Right. And we are privacy compliant! I’ve subliminally says, “Oh, Beyoncé drinks diet Pepsi.
of computer vision. For instance, we do virtual become an expert in privacy law, unfortunately. I should try that.” [chuckles] It just is what it is!
zones, based on a lot of trig and calculus, be- Who would have known that I would be? World-
cause we don’t get depth out of commodity cam- wide! Markus: How worried are you about that? By the
eras. We have to do in-depth math based on what way, I had a similar talk with fellow RD Ciprian
the computer sees visually in a flat image. We Markus: And a lot of fun that stuff is! [another Regional Director] yesterday. What we
have cameras in places like a digital sign and we talked about was the ability to use AI or machine
play interesting content on that sign. It’s typi- Tim: But you have to be an expert! For instance, learning and pattern recognition to identify that
cally beautiful people doing beautiful things. Like the privacy in your home-world, as you’re so close subset of people that are most easily swayed but
beautiful people drinking champagne and scant- to Germany, is very very strict. [Note: Markus is could be tremendously important. It brings us
ily clad women dancing around with champagne. originally from Austria, and CODE still has offices full circle back to the election stuff and things
And all this is done in the hope of getting the there that Markus visits a few times a year.] The like Brexit, right?

In this feature, we eavesdrop on a conversation between Tim Huckaby and Markus Egger, both seasoned Regional Directors.
Talk to Tim about: Talk to Markus about:
Hololens, computer vision, Microsoft Cognitive machine learning and AI, ASP.NET, HTML apps
Services, emerging experiences, augmented (including Angular, Vue.js, etc.), the cloud,
and mixed reality. Azure, Microservices, Windows applications,
You can contact him at timh@interknowlogy.com software strategy, and much more.
You can contact him at markus@eps-software.com

Tim Huckaby is an industry luminary focused on AI, computer vision, Markus Egger is not just an RD, but as the founder and publisher of CODE
machine learning, AR/MR, and emerging user experiences. Tim has over Magazine, he’s also directly associated with this publication. In his main
35 years of technology experience including working on a server product job, he is the President and Chief Software Architect of EPS Software Corp.
team as a development lead at Microsoft. He worked on Microsoft Server (a company better known for its CODE brands such as CODE Consulting,
products in the late nineties. Tim is a Microsoft Global RD, a Microsoft MVP in CODE Training, CODE Staffing, and CODE Magazine). He is also the founder
AI, and serves on many councils and boards. He has received many awards of other business ventures, such as Tower 48, Wikinome, and others. In his
for the highest-rated technical and industry presentations and for keynotes own words, he spends his time “like most software developers, writing
for Microsoft and many other vertical and technology conferences like CES production code” both for consulting and custom app-dev customers,
and events all around the world. Tim is consistently rated in the top 10% of and also for his own companies. He has worked for some of the largest
all speakers at these events. Having worked for or with Microsoft for close to companies, including many Fortune 500 companies, such as Microsoft.
30 years, he’s been on stage with, and done numerous keynote demos for, Markus often takes on the role as a “CTO for hire.”
many Microsoft executives, including Bill Gates and Steve Ballmer.

codemag.com Talk to an RD: Tim Huckaby and Markus Egger 63


TALK TO AN RD

Tim: Yeah. The election is its own monster. And answer is “no.” No! They still have super high car level. Our governments need help in understand-
“Chippy” [Ciprian] as I call him, like you, is a bril- insurance. ing this stuff. Here’s a great example. The federal
liant speaker. I sat in his session also and was just privacy law is in contradiction with California’s
in awe because he does a presentation where his Markus: What if it goes the other way? privacy law, which is in contradiction with San
content is basically about a dozen words. It’s 12 Francisco’s privacy law. Just recently, the city
slides each with one word on it and he just talks Tim: I don’t know. They probably wouldn’t. The of San Francisco panicked because government
for an hour and it’s so riveting. That said, you answer is still “no.” people were making technology decisions based
know, we have this responsibility and ethics in on a very poor Amazon algorithm, and made the
AI, and I’m all about it. You know, that’s what the Markus: You know, one of the things that I always assumption that all facial recognition is bad and
panel was today. We have this “nuclear weapon” wonder about, I know we’re both really passion- could produce false positives that would invade
we call artificial intelligence and it’s over-hyped ate about computer vision, but also the bigger people’s privacy to the point where we’d acci-
and it’s been around for years. It’s not brand AI topic, right? And I’m not a big believer in AI dentally arrest someone. And the simple fact is
new. For instance, take actuaries, which have taking over the world and the “Terminator Sce- that facial recognition is a solved problem. It was
been around for a hundred years. Actuaries have nario”... solved two or three years ago. It’s also not really
the hardest degree to get in the US. It’s a math known that Microsoft has the NIST-awarded best
degree, but it’s well beyond a doctor. It takes Tim: The dystopian view. facial recognition,
something like 18 years to get this actuary de-
gree. There’s only about a hundred of them in the Markus: Right. What I do wonder about is a Markus: That’s a standardized test, which is un-
world. They’re the ones who do the algorithms slightly different angle of this, and it’s just, is usual in AI.
for insurance companies. There are very few actu- society in risk of a breakdown because of these
aries who don’t work for an insurance company. sorts of things where you could identify those Tim: The NIST is the National Institutional for
They are immediately biased, these people. Or who are easily swayed and fake news and fake Standards and Technology. And Microsoft submit-
perhaps not these people, but the insurance in- fact checking and fake this and that and iden- ted for the first time ever. NEC has won this thing
dustry. And a great example of something that’s tifying, I mean, it’s relatively easy as a compu- forever, for the last 25 years. NEC offers wildly
atrocious that’s been going on forever and will tational pattern-matching problem these days to expensive security systems. They’re great at what
still go on, which is completely ignored, is shown recognize those who are easily fooled, right? they do there. They run in all the airports and all
by the use case of auto insurance. Let’s go with over the world, you know, they’re the ones look-
Chicago, which has very strict privacy law. One Tim: Yeah. ing for terrorists and stuff, but Microsoft won,
of the U.S. states with a very strict privacy law because they have so much talent in R&D.
that’s contradictory to the federal privacy law. Markus: And in Brexit, we’ve seen that, right?
But that’s a different issue. We can get to that in There was a group of people who’ve never voted Markus: By quite a margin, if I remember cor-
politics. In the inner city, in Chicago, the south before, who were identified as such and were rectly, right?
side of Chicago, what happens is the car insur- identified as easily swayed and heavily marketed
ance rates are dramatically higher than just five toward with very questionable information, to Tim: Yeah. 98% in the test that mattered. They
miles away in the suburbs. And it’s solely because put it diplomatically. That’s a tough problem and did a number of tests, but the tests that mat-
the data science says that they’re riskier, that a difficult to prevent. tered were profile, occlusion by hat or sunglasses,
particular race is more risky, and that race is 98% beard, and facial hair, stuff like that. Movement.
of the south side of Chicago. In the suburbs, it’s Tim: That demographic I talked about earlier that And they got 99.6% accuracy in perfect environ-
a different race of people who are statistically was swayed by diet Pepsi, we’re not allowed to ments. Good input produces good output. NEC
proven to be safer drivers. This has been going say which one it is, but we all know, um, yeah, wasn’t far behind, but they did lose. NEC won in
on for years! we’re, we’re at a dilemma point here. And, um, the test where you’re being photographed. So
the whole panel this morning was all about this you step in front of a well-lit camera.
Markus: And are you really talking about race and the dilemma point is that we’ve got this “nu-
or they are just labeling whoever lives in those clear weapon,” but you could also produce clean Markus: Like immigration.
areas? energy and it can produce the microwave oven.
Tim: Exactly. And you look straight into it and
Tim: Well there’s... there’s... [thinks]...[sighs]...I Markus: Oh, absolutely. Yeah. they only won by a percentage point. Their ac-
don’t know. We’re not actuaries, we don’t build curacy was like 99.5% or something like that?
this software. But Microsoft frequently uses this Tim: I mean, what do we get out of nuclear pow- The point is that this is a solved problem. When
example of bias in AI. And the dilemma is, “okay, er? We’ve got the microwave. Right? you take this away from the police officers and
evil insurance company, so you can prove that the FBI in San Francisco, you’re providing a risk
this is the case. This particular demographic is Markus: No, I mean, the potential for good is to the population that makes them unsafe and
riskier than that one. But what if one of these great. it’s simply based on hysteria. Do you know Tim
moves into there?” I’m pointing with my hands O’Brien from Microsoft? This is his job. He and
[gestures from one place to another], but what Tim: The potential for good is great. Our dilemma his boss, Brad Smith, the corporate VP. Respon-
if someone from the south side of Chicago moves is our governments, whether they be at a federal sibility in AI is their job and they’re leading this
into the suburbs? Do you change their rate? The level or at a state level, or at a civic level, a city charge for Microsoft. And Tim will tell you, “if

64 Tim Huckaby and Markus Egger codemag.com


TALK TO AN RD

you’re worried about facial recognition, you’re Tim: And they don’t have privacy laws, they don’t Tim: That makes a blind man see in a non-dys-
nuts. Because the deep fakes thing is real.” There have privacy. They’re making whatever they want. topian way, a non-negative way of looking at it.
are other “nuclear weapons” that are in the AI That means the guys wearing the glasses, it might
space and they’re not “facial recognition.” We Markus: Exactly! China’s doing this social score have one hell of a battery on his backpack, right?
could help the world with facial recognition. thing and detecting when people do things like Forget about that weakness. But he’s wearing a
walking across at red lights. That’s technological- pair of glasses and there’s a CPU and a computer
Markus: The audio fakes are incredibly scary. But ly very interesting. But it’s certainly an Orwellian in there and it’s telling him everything in front of
it’s also the video stuff that’s pretty far along. state going on there, right? him. Everything! Hundreds of millions of objects.
The deep fake stuff is amazing, right? I mean, put God knows how that would happen. Like noth-
a fork in it! It’s done and here to stay and we will Tim: Orwell, Huxley wrote books about this dys- ing’s going to replace the human vision system.
have to deal with it. This is not science fiction. topian view. You know, I’m totally into Moore’s It didn’t matter how quickly a CPU calculates,
Law. Remember when Bill Gates 20 years ago right? Nothing would be able to be able to suck
Tim: I’m not sure how much of this we can say used to do the digital decades speech and he in that much information at once. But you could
in public, but there was the incident of high- talked about Moore’s Law and how it’s going to do object recognition of hundreds of millions of
level Microsoft executives playing around with help us, software people in blah, blah, blah. things with that type of processing power. Right?
their voice technology and voice synthesis. They Most people probably know what it is, but to re-
quickly realized how incredibly powerful and dan- cap quickly, Moore’s Law is basically a prediction Markus: And that brings us right back around.
gerous that technology can be. And they imme- by the genius before he founded Intel and who Right? It’s kind of fun as we sit here and chat to
diately said “yeah, that’s a nuclear weapon. We was a young man at the time. He saw a trend that talk about the dystopian future. But the reality is
are not giving them to the world.” And they’re we were cramming twice as many transistors on both of our companies use this stuff to do good
keeping it under lock and key. a circuit board and he predicted that would go things, right? If we don’t, we wouldn’t admit it.
on for another decade. Well, it’s gone on for Right? [laughs] But there are a lot of interesting
Markus: It’s good that a conscientious company like 55 years and it equates to CPU power. So now things we do, I mean, you try to make the world
Microsoft is at the forefront of this. Did you hear our CPUs are calculating at the speed of small a better place.
that they just were voted the most ethical company animals like rabbits, like 10 trillion. I could get
in the US? They have a business model that isn’t the dystopian view of it. We are heading for the Tim: I want to be there! We did a project that
based on doing stuff like that and then selling the singularity, if Moore’s Law continues. By 2025, brought everyone to tears from Microsoft in PUV,
data. But there are many others. And the danger the Intel CPU will be calculating at the speed of uh, “Posterior Urethral Valve Syndrome,” and if
is that other companies are eventually going to do the human brain. That doesn’t mean machines missed by the physician, it has a 100% mortality
something similar. It’s probably inevitable. are taking over the world. It just means that in rate. It’s a very rare syndrome. And if the physi-
computer vision, we’re going to be able to see a cian isn’t trained to see it and they miss it, the
Tim: Right. Remember when Satya Nadella did lot more. You did a demo at the session you just baby dies. If they’re trained, it’s very simple to
his keynote at BUILD 2016? He talked a lot about presented, of looking at a handful of fish under recognize, but they’re human so they miss it. This
ethical AI. And without getting into too much the water. But how about recognizing every cor- is an AI replacing doctors. These are simple tools
detail, that caused a lot of unhappy reactions al uniquely at the same time or the algae at the like, “hey doctor, look at this one. We’re 67%. The
from certain competitor companies that are ex- same time? And the water clarity and tempera- computer is 67% confident that it’s PUV. Maybe
actly in the business of selling that kind of data ture, which is a big deal for our world. If you’re you should take a peek at that.” And it’s really
and not acting ethically. Satya shocked the press into CO2 buildup and climate change and all that simple to fix, by the way. From “100% fatal” to
and analyst community because he talked about stuff. It’s scary. What if you could see all that? “simple to fix,” just like that.
responsibility in AI and he talked about this dys- We can’t do that now because we don’t have
topian view. enough processing power. Simple as that. It’s Markus: That’s a lot of the stuff we do too, right?
one of the few times in our world, Markus, where Where it’s not just “are we better than a human
Markus: Yeah. I was at that keynote. Nice that the software is waiting for the hardware. Nor- eye.” It’s also everybody paying attention and
somebody is at the helm whose main business mally it’s the other way around, right? But, but then bringing things to people’s attention. We
model is not that. the real dystopian view is, okay, so you get to have a lot of things we built on AI in general and
2025 and we have these amazing CPUs that cal- on vision specifically where it’s really just, “this
Tim: Exactly! There’s the point that Microsoft is in culate the speed of the human brain, which sim- is something you should take a look at.” Are they
a unique position to be the leader in ethics in AI ply means that you can see a bunch more things, making a call on it? But it’s bringing it to some-
because their revenue isn’t based on advertising but you can’t make a blind man see. You’ll be body’s attention.
or tracking people like these other companies. able to see maybe, I dunno, 150 things and rec-
It’s a consumptive model in a cloud. ognize them all with confidence under the wa- Tim: Exactly!
ter. By 2045, if the trend continues, we’ll have a
Markus: It’s interesting what’s going on in Asia. CPU that will calculate at the speed of all the hu- Markus: “Here’s 10,000 things. You, the human
I mean, Asian players—whether that’s the gov- mans combined on the earth. Now that is, like, can’t look through all this, but we’ll highlight the
ernment of China or whether that’s players like whoa. hundred most important ones that you should
Alibaba, Baidu, or different ones—what they do take a look at manually.” That’s how I see a lot
with tracking… Markus: That’s mind blowing. of AI work going forward. And that provides real

codemag.com Tim Huckaby and Markus Egger 65


TALK TO AN RD

benefits in all kinds of apps. Including conven- are you doing? Welcome to the booth. Um, what’s joyed it. Definitely well done this year. I’ve missed
tional business apps that most of us have been your name? And, uh, you know—can you prove a few [DevIntersection conferences] and I’ve al-
building for decades. We are doing quite a bit it?” [laughs] And sure enough, this guy proved it ways enjoyed them, but this one even more so.
of that with our customers and they get great wasn’t him. It just looked exactly like him. I think
benefits in scenarios where initially they never that’s important because we’re not going to be Tim: Yeah, they do a good job. And good talking
thought AI would be for them at all. replacing police with machines—that’s danger- to you.
ous. That’s seriously dangerous.
Tim: I’ll give you an exact example, a use case of Markus: Good talking to you too! I’ll see you at
that. I can’t say the companies involved, but one Markus: That’s interesting stuff. That’s a very the MVP Summit!
might speculate the largest software company in good example and an interesting scenario. A lot
the world that’s in the Silicon Valley whose sole of this is more pedestrian, right? For instance,  Markus Egger
revenue is based on advertising. Okay? Even they we help companies optimize their turnover in the 
have bad guys. They have a bad guy database. warehouse by 5% or 10% using this technology.
There are others too. The famous one is Taylor Those things are huge for most businesses. Those
Swift. Taylor Swift has over 2,500 bad guys in her are probably more everyday scenarios. But yeah,
database. Don’t ask me how I know that, but it’s I mean those scenarios you just mentioned are
over 2,500 people. Not “Miss Swift, I hate you. certainly amazing and I think will change things
You’re ugly and your music sucks.” This is, “I want for the better. I think this will get a lot of use on
to kill you,” or “I want to do awful things to you” a variety of fronts in very positive ways.
where a federal authority has gotten involved and
produced some type of incarceration or restrain- Tim: Yeah, I am optimistic.
ing order or something. That’s 2,500 people for
Miss Swift alone! Well, even the CEO of a large Markus: I think we’ll be able to use that technol-
tech company has people that hate him, right? ogy to do things like identify deep fakes. For a
People that threatened him credibly. Mostly while at least. But that’s going to get tougher
they’re Internet trolls who say stupid things, but and tougher.
it catches the FBI’s attention. So I’m at this giant
event, and we’re looking for the bad guy because Tim: Deep fakes is the one that scares me. All the
they’re afraid that one of these particular bad other stuff. If we just get government smart, and
guys is going to get into the booth at CES and we have some governments and regulation, which
cause havoc. Microsoft has basically told the United States
federal government and other governments in
So we are monitoring this conference with the Europe, you need to put in regulation to control
VSBLTY software and looking for people with a this monster. The Deep States Fakes thing worries
certain degree of confidence. But we bring the me. It does. Because I’ve seen even super smart
confidence throttle way down on that one guy. technology people get fooled. And if those peo-
Everyone else is like 60%, 65%. We send an alert ple are getting fooled, then Grandma Huckaby
if we’re 65%, but with this guy, we pulled it down has no shot. She’s doomed. Right?
to 40%. They’re okay with false positives because
humans are going to make a decision, right? We Markus: Yes. The fakes are just getting so good!
got 15 false positives on this guy and they deploy
on one. And I was in the security center, standing Tim: And how do some of these fakes make it
behind all these security guys when it was go- through the filters?!? Just the phishing stuff.
ing down. And we are looking at this nice portal How do they make it through the Office 365 fil-
we built. The alerts come in and they’re looking ter? I don’t get that. I got a phishing email on
at what the software sees and they’re looking at Thursday that was so good. I brought engineers
the original image in the facial recognition data- into my office and said, you got to look at this
base. Then they’re looking back at the live feed one. Like how did they pull it off? I don’t know
showing this person. And I’m looking at him, and the answer. No one did. It was from a microsoft.
I’m like, “that’s the guy! That’s the guy!” And we com domain. The content was very good and tar-
were getting, I don’t know, 67% confidence or geted. How did they pull that off?
something like that. And I’m like, “that’s him!”
I’m saying this to myself. And in their security Markus: Yeah. It’s gotten a lot more sophisti-
mumbo jumbo, they’re saying the same thing. So cated. And a lot more targeted with the “spear
it’s not like they ran out there and shot the guy. phishing” attacks. I’ve heard the term “laser
Instead, they simply deploy security officers who phishing” used quite a bit lately. Well, it was a
walk up to the person, and they say “Hey, how great conference though, wasn’t it? I really en-

66 Tim Huckaby and Markus Egger codemag.com


ONLINE QUICK ID 2003081

CSLA .NET:
A Home for Your Business Logic
As .NET developers, the tools we have are pretty impressive. You can choose from numerous UI frameworks such as UWP, WPF,
Windows Forms, and various Web client UI frameworks like Angular and React. And you have multiple options for interacting
with databases, such as Entity Framework, Dapper, and others. What about business logic? How do you organize your business

logic into a maintainable layer with clear separation of con- validation, authorization, and algorithmic processing. It’s
cerns from the presentation and data layers? Business logic incredibly easy to allow business logic to leak into the pre-
is at least as important as the UI or data, and yet it’s the sentation layers, especially validation and authorization.
layer of every app that has little or no rigor in terms of ar- And it also takes a lot of discipline to prevent data access
chitecture or repeatable coding patterns. logic from leaking up into the business or presentation lay-
ers.
This is the purpose of the MIT-licensed open-source framework
CSLA .NET: to provide first-class framework support for busi- Separation of concerns is one of the best techniques you
ness logic, like your options at the UI and data access layers. can use to improve the maintainability and long-term reus-
Rockford Lhotka CSLA got its start in the mid-1990s as a freeware framework ability of your code. Design patterns like MVC and MVVM are
rocky@lhotka.net supporting DCOM, and in the context of a freeware project, specifically focused on separation of concerns, showing how
blog.lhotka.net I reimplemented it for .NET in 2002. Of course, these days, to separate views, interface control, and UI event handling
twitter.com/rockylhotka “freeware” is better known as open source, and the license was into their own components. Interestingly enough, neither
switched to the widely accepted MIT license many years ago. of these patterns speak to how or where to put business
Rockford Lhotka is CTO
at Magenic and is the You can find CSLA .NET at https://cslanet.com and on GitHub. logic: just that the logic shouldn’t go in the views, control-
creator of the open source lers, or viewmodels.
CSLA .NET development
framework. He’s the author
CSLA .NET Application Architecture When it comes to implementing business logic, you might
of numerous books, CSLA .NET is designed to support a specific architecture, do what most people do and end up putting some or all of it
and regularly speaks at as shown in Figure 1. This architecture has clean separa- in a controller or viewmodel, even though that directly vio-
major conferences around tion between the interface and interface control layers, lates those design patterns. Or you might create a function
the world. Rockford is typically, something like HTML or JSON and controllers or library or set of services that are invoked by the controller
a member of the Microsoft viewmodels. And it has clean separation between the data or viewmodel. And that’s a very good solution to be sure!
Regional Director and access and data storage layers, often Entity Framework or
MVP programs. Magenic ADO.NET and SQL Server. The part of the architecture CSLA CSLA takes a different approach, by making the model it-
(magenic.com) helps .NET focuses on is the business layer in the center. self into a repository for business logic. This is particularly
you deliver your digital beneficial when using .NET, because CSLA also makes your
products to market faster. Like many developers, you may find it difficult to totally model bindable against every UI framework supported by
For more information separate all business logic into its own layer that includes .NET (from Windows Forms through ASP.NET to Blazor with
about the author,
go to lhotka.net.

Figure 1: CSLA .NET layered architecture

68 CSLA .NET: A Home for Your Business Logic codemag.com


WebAssembly). If your model supports data binding, and
also encapsulates all of your business logic, you’ll find that
it’s very easy to create highly interactive user experiences
while still maintaining complete separation of concerns be-
tween the presentation layers and the business layer.

It’s also the case that CSLA is very prescriptive about how
and where you invoke your data access layer. Again, the
intent is to help you preserve separation of concerns by
formalizing the ideas of a business layer and a data access
layer. CSLA doesn’t care what technologies you use to in-
teract with the database(s), so you can use Dapper, Entity
Framework, raw ADO.NET, or whatever other technologies
work for you. The important part is that CSLA helps you keep
your data access code in its own layer, separate from the
business or presentation layers.

A Simple Blazor App Figure 2: Blazor and CSLA solution in Visual Studio
The best way to show you CSLA is to build an app, and the
most modern type of UI technology at the moment is Blazor
using WebAssembly to run .NET in any modern browser. capsulates the business rules necessary to allow the user to
Building this app currently requires the use of Visual Stu- edit information about a person. It’s used by the EditPer-
dio 2019 Preview and .NET Core 3.1 Preview. You can find son.razor page.
the latest code for this example on GitHub in the CSLA .NET
repo (https://github.com/MarimerLLC/csla/tree/master/ There are also some rule classes that implement business rules:
Samples/BlazorExample). InfoText, CheckCase, LetterCount, and NoZAllowed. One of the
most important features of CSLA is its rules engine, which hon-
Keep in mind that the same architecture, business code, and ors rules from the System.ComponentModel.DataAnnotations A Home for Business Logic
data access concepts apply unchanged to any other .NET namespace as well as rules implemented as classes.
UI framework, including ASP.NET Razor Pages, MVC, WPF, CSLA .NET is a framework
Xamarin, and others. The /Samples directory in the CSLA Because the BlazorExample.Shared project uses CSLA, it ref- intended to provide support
GitHub repo include examples of these other UI frameworks erences the Csla NuGet package. for your business logic, similar
to the UI and data access
as well.
frameworks available in the
The PersonInfo class is very simple, exposing read-only
.NET ecosystem.
Solution Structure properties using the CSLA property declaration model as
Most client-side Blazor apps include a client-side project shown in Listing 1.
that compiles to WebAssembly, and this code runs in the CSLA .NET Rules Engine
browser on the client device. And they have a server-side CSLA is prescriptive about property declarations, so they
project that’s used to deploy the code to the client, as well all follow the same pattern. This increases readability and This article just scratched
as exposing service endpoints. They also have a shared proj- maintainability of code, and it reinforces the idea that busi- the surface of the CSLA rules
ect containing code that you want to deploy to both client ness rules should be implemented using the CSLA rules en- engine. This engine allows you
to write sync and async rules
and server. This is illustrated in Figure 2. gine rather than random code in a property setter. Notice
that run on client and/or server
the use of the Display attribute to provide a friendly name
environments, validating and
This is the same model CSLA that .NET has used over its 23+ for the property. This is an example of how CSLA supports
affecting properties within
years, and so it’s a natural fit to use with Blazor. I’ve always the use of the System.ComponentModel.DataAnnotations one object, or across an entire
recommended having a Class Library project that builds a attributes. object graph.
DLL to contain business logic, with that assembly deployed
to client and server. The more interesting class is PersonEdit, because it imple- The rules engine has been
ments read-write properties that have business rules at- used to create highly
Also notice that this solution has a DataAccess project to tached. For example, the next snippet shows a PersonEdit sophisticated enterprise
help maintain the separation of concerns between the busi- property. apps, including software to
ness layer (the BlazorExample.Shared project) and the code run large banks, telecom,
used to interact with the data store. In this example, the public static readonly transportation, manufacturing,
data store is a mock in-memory database built using col- PropertyInfo<string> NameProperty = and other industries.
lections, but it could as easily be a SQL Server accessed via
Dapper. I won’t discuss the data access layer in this article,
although I’ll show how and where it’s invoked. Listing 1: Read-Only Name Property
public static readonly
The Business Layer PropertyInfo<string> NameProperty =
The BlazorExample.Shared project contains three business RegisterProperty<string>(nameof(Name));
classes: PersonList, PersonInfo, and PersonEdit. The Per- [Display(Name = "Person name")]
public string Name
sonList and PersonInfo classes work together to provide a {
read-only list of information about the people available to get { return GetProperty(NameProperty); }
the user, and they are used by the ListPersons.razor page. private set { LoadProperty(NameProperty, value); }
The PersonEdit class exposes read-write properties and en- }

codemag.com CSLA .NET: A Home for Your Business Logic 69


Listing 2: Rule to Return Warning Message BusinessRules.AddRule(
new InfoText(
protected override void Execute(IRuleContext context)
NameProperty,
{
var text = (string)ReadProperty( "Person name (required)"));
context.Target, PrimaryProperty); BusinessRules.AddRule(
if (string.IsNullOrWhiteSpace(text)) return; new CheckCase(NameProperty));
var ideal = text.Substring(0, 1).ToUpper(); BusinessRules.AddRule(
ideal += text.Substring(1).ToLower();
if (text != ideal) new NoZAllowed(NameProperty));
context.AddWarningResult("Check capitalization"); BusinessRules.AddRule(
} new LetterCount(
NameProperty, NameLengthProperty));
}
Listing 3: LetterCount Rule Implementation
You can see that a rule is attached to a property by creating
protected override void Execute(IRuleContext context) an instance of the rule and providing the static PropertyInfo
{
var text = (string)ReadProperty( descriptor as a parameter. Some rules require other param-
context.Target, PrimaryProperty); eters as well.
var count = text.Length;
context.AddOutValue(AffectedProperties[1], count); Some rules provide information, warnings, or error valida-
}
tion messages to the user. Error level messages, like the
Required attribute, also prevent the business domain ob-
ject from being saved, as the object is considered invalid.
Listing 4: Fetch Method in PersonEdit Class Listing 2 shows how easy it is to implement a warning rule.
[Fetch] Rule classes implement the IBusinessRule interface or sub-
private void Fetch(int id, [Inject]DataAccess.IPersonDal dal) class the BusinessRule base class. In any case, they imple-
{ ment an Execute or ExecuteAsync method containing the
  var data = dal.Get(id); rule.
  using (BypassPropertyChecks)
    Csla.Data.DataMapper.Map(data, this);
  BusinessRules.CheckRules();
}
But rules aren’t just for validation;
they can also manipulate property
Listing 5: Binding to the Name property from the PersonEdit Object
values.
@if (vm.GetPropertyInfo<string>(nameof(vm.Model.Name)).CanRead)
{
  <tr>
    <td>@(vm.GetPropertyInfo<string>(nameof(vm.Model.Name)). You can see how this rule reads the property value from the
FriendlyName)</td> target business object and then checks to see if it has prop-
    <td> er capitalization. If the capitalization isn’t ideal, a warning
      <TextInput Property=”@(vm.GetPropertyInfo<string>(
nameof(vm.Model.Name)))” /> message is returned so the UI can display it to the user as
    </td> appropriate for the current user experience.
  </tr>
} But rules aren’t just for validation; they can also manipulate
property values. Listing 3 shows a simple rule that counts
the number of characters in one string property and up-
Contributing to CSLA .NET RegisterProperty<string>(nameof(Name)); dates the value of a different int property with that length.
[Display(Name = "Person name")]
CSLA .NET is an MIT-licensed [Required] This rule also reads the property value of the primary prop-
open source project on public string Name erty, and then it asks the CSLA rules engine to set the value
GitHub. The easiest way { of another property (AffectedProperties[1]) to the length of
to use the framework is get { return GetProperty(NameProperty); } the primary property.
by referencing the NuGet set { SetProperty(NameProperty, value); }
packages. You can get all the
} You can see how these rules are abstracted, in that they
code and samples from NuGet.
don’t know about the type of business domain object against
The CSLA .NET project team The coding pattern for this property is essentially the same which they’re running. They just know to read some proper-
loves getting pull requests! as for the read-only property, so you can see the consis- ties, update other properties, or return error, warning, or
Join the forum, the Gitter tency in how properties are declared. You should also notice information text. The goal is that you can create and test
channel, and the main repo that this property uses the Required attribute to indicate your rule classes, and then attach those rules to properties
to discuss the future of the that this is a required property. in any business class where the property should apply.
framework and to get involved.
Other rules are attached to properties in the AddBusiness- Interacting with the Data Access Layer
Rules method as shown in the next snippet: The final aspect of the business layer is that it relies on CSLA
to formalize how and when to invoke the data access layer.
protected override void AddBusinessRules() For example, Listing 4 shows how the PersonEdit class im-
{ plements a CSLA-invoked method to get data from the data
base.AddBusinessRules(); access layer.

70 CSLA .NET: A Home for Your Business Logic codemag.com


The CSLA framework manages the lifetime of domain ob- Listing 6: TextInput Blazor UI Component
jects, and invokes methods attributed with Create, Fetch,
<div>
Insert, Update, and Delete attributes (among others) as   <input @bind-value=”Property.Value” @bind-value:event=”oninput”
appropriate. You’re responsible for implementing these          disabled=”@(!Property.CanWrite)” /><br />
methods to interact with your data access layer to perform   <span class=”text-danger”>@Property.ErrorText</span>
the requested action. In this example, notice how a refer-   <span class=”text-warning”>@Property.WarningText</span>
  <span class=”text-info”>@Property.InformationText</span>
ence to the data access layer is provided via dependency </div>
injection as defined in the standard application Startup.
cs file. @code {
  [Parameter]
The data access layer is invoked to get the requested data,   public Csla.Blazor.PropertyInfo<string> Property { get; set; }
}
and that data is copied into the properties of the business
domain object. Then business rules are run against the
newly loaded data so that any broken rules will be visible
to the user. Listing 7: Auto-Disabling the Save Button
<button @onclick=”vm.SaveAsync” 
Now let’s see how these business classes are used to create a disabled=”@(!vm.Model.IsSavable)”>Save person</button>
Blazor UI through their support for data binding.

The Interface and Interface Control Layers editing a person based on the PersonEdit business class. This SPONSORED SIDEBAR:
The BlazorExample.Client project implements a client-side next snippet shows how the page navigation, namespaces,
Blazor app that can run in any modern “evergreen” browser, and dependency injection is set up. Need FREE Project
including Chrome, Firefox, Safari, and Edge; on desktop, Advice?
laptop, tablet, and phone devices. Because Blazor apps @page "/EditPerson" CODE Can Help!
are built using .NET, the assembly from the BlazorExample. @page "/EditPerson/{id}"
Shared can be deployed to the client device, providing a @using BlazorExample.Shared
How does no-strings free
advice on a new or existing
highly interactive user experience. @inject Csla.Blazor.ViewModel<PersonEdit> vm
software development
@inject NavigationManager NavigationManager
project sound? CODE
Blazor apps use a variant of the Razor syntax that has been @attribute [Authorize(Roles = "Admin")]
Consulting experts have
used by ASP.NET MVC for many years. Each Blazor page is experience in cloud,
defined in a file with a .razor extension. For example, the Although CSLA is primarily focused on the business layer, Web, desktop, mobile,
Pages/EditPerson.razor page provides the UI for creating or CSLA does provide some helper types to streamline interac- microservices, and DevOps
projects. Contact us today
to schedule your free hour
of CODE consulting call
with our expert consultants
(not a sales call!).
For more information
visit www.codemag.com/
consulting or email us at
info@codemag.com.

Figure 3: EditPerson page with broken validation rules

codemag.com CSLA .NET: A Home for Your Business Logic 71


tion with each type of .NET UI framework. This project refer- Figure 3 is an example of the Blazor app in action, where
ences the Csla.Blazor NuGet package and so has access to I’ve entered a Name value that triggers all the rules. Notice
these helper types, including a ViewModel class that can be how the Save button is disabled because the Name property
injected into pages when declared in the standard Startup. currently violates an error-severity validation rule.
cs file. This ViewModel type abstracts common repetitive
code that you would have to write in nearly every page.
Conclusion
The page uses Razor syntax to build the UI for the user. This The purpose of CSLA .NET is to provide a first-class home for
includes the use of data binding against the ViewModel and business logic, similar to the first-class UI and data access
PersonEdit business type. Listing 5 shows how the Name experiences provided by the .NET ecosystem. You can use
property is displayed to the user by using a TextInput Blazor CSLA to create consistent, maintainable business logic that
component. encapsulates validation, authorization, and algorithmic
processing. The resulting business assembly can run any-
The code in Listing 5 illustrates how the separation of con- where you can run .NET, including Linux and Windows serv-
cerns between the presentation layers and business layer ers, containers, Windows clients, and mobile clients. And
helps create a flexible user experience. Notice that this code now with client-side Blazor, you can run your business logic
block is only displayed if the current user can read the prop- in any modern browser on any device.
erty, thanks to the CanRead property exposed by the View-
Model type. You can also see how the FriendlyName property  Rockford Lhotka
is used to display the friendly name of the property from the 
Display attribute in the PersonEdit business class. And the
TextInput component is provided with information about
the property the user can edit.

The TextInput component is a custom UI component I creat-


ed based on the Blazor component model. It’s implemented
in the Shared/TextInput.razor file as shown in Listing 6.

Blazor components are the mechanism by which you create


reusable bits of UI. This component requires a Csla.Blazor.
PropertyInfo object as a parameter, and it uses that object
as a binding source for the various UI elements in the Razor
markup.

You can see how the input element is bound to the Value
property, with the @bind-value:event=”oninput” parame-
ter indicating that the underlying model should be updated
on each keystroke. Also notice how the input element will be
disabled if the current user isn’t authorized to change the
property value by checking the CanWrite value provided by
CSLA. Finally, you should notice how the error, warning, and
informational text values are displayed to the user. These
are the values generated by the rules attached to the Name
property in the PersonEdit business class.

The important thing you should understand is that neither


the EditPerson page nor the TextInput component have any
knowledge of business rules. No validation, authorization,
or algorithmic processing is implemented in the presenta-
tion layer. All that business logic is implemented in the
business layer, and the presentation layer is solely respon-
sible for altering the UI so the user has a great experience
based on the information provided by CSLA and your busi-
ness code.

Back in the EditPerson.razor page, there’s one last detail


I want you to see, and that is how the Save button is only
enabled if the business object can be saved. This is shown
in Listing 7.

Like in the previous code, you can see how the element’s
disabled property is set based on the IsSavable property
provided by CSLA. By default, CSLA considers a business ob-
ject “savable” if there are no error rules broken, the object
has been changed, and the current user is authorized to
save the object.

72 CSLA .NET: A Home for Your Business Logic codemag.com


CODE COMPILERS

(Continued from 74)

understand that most of what you’re afraid to


face is the feelings of “being a quitter” or the fear Mar/Apr 2020
that “if I give up now, I’ll never know if that next Volume 21 Issue 2
corner was the one that would’ve made me win.”
Nobody can predict the future, but sometimes, Group Publisher
that pivot, that willingness to turn away and try Markus Egger
something new, is exactly what leads you to that Associate Publisher
success or “win” that we crave, too. Rick Strahl

Editor-in-Chief
It’s okay to say “It’s time” and try something else. Rod Paddock

Managing Editor
Summary Ellen Whitney

Speaking of endings, it’s time. This will be the Content Editor


Melanie Spiller
last editorial I write for CODE Magazine.
Editorial Contributors
Otto Dobretsberger
I’ve enjoyed the time I’ve had here; I’ve enjoyed Jim Duffy
reading the various responses that you have Jeff Etter
posted to me over Twitter, and the conversations Mike Yeager
we’ve had at conferences, and the exchanges Writers In This Issue
we’ve posted back and forth over email and such. Markus Egger Wei-Meng Lee
The CODE Magazine audience is a great audience Rockford Lhotka Sahil Malik
Peter Mbanugo Rod Paddock
to write for, and I’ve learned as much from you John V. Petersen Paul D. Sheriff
as I have anything else in my life. Walking away
from a thing I’ve enjoyed is never easy, but when Images for “Devs” on FX on Hulu are courtesy of FX Networks
Copyright 2020, FX Networks. All rights reserved.
I did that same bit of reflection and meditation
and examination of the future and what it held, Technical Reviewers
a thought crystallized: It’s time to hang up the Markus Egger
Rod Paddock
Microsoft Word template, and put the time spent
on these editorials into other endeavors and Production
projects. Franz Wimmer
King Laurin GmbH
39057 St. Michael/Eppan, Italy
My thanks to Rod Paddock for the opportunity to
reach out to you for all these years. My thanks to Printing
Fry Communications, Inc.
the rest of the CODE Magazine authors for keep- 800 West Church Rd.
ing the quality bar high and the “interesting top- Mechanicsburg, PA 17055
ic” bar even higher, so that I could piggyback my Advertising Sales
words on the backs of your amazing work. Most Tammy Ferguson
of all, my thanks to all of you, the audience, for 832-717-4445 ext 26
allowing me to put these ideas in my head down tammy@codemag.com
onto paper (er…Word doc), because forcing my- Circulation & Distribution
self to do so made me think so much more deeper General Circulation: EPS Software Corp.
Newsstand: The NEWS Group (TNG)
about them than I would have otherwise. Media Solutions

Douglas Adams put it best: So long, and thanks Subscriptions


Subscription Manager
for all the fish. Colleen Cade
ccade@codemag.com
 Ted Neward
US subscriptions are US $29.99 for one year. Subscriptions
 outside the US are US $49.99. Payments should be made
in US dollars drawn on a US bank. American Express,
MasterCard, Visa, and Discover credit cards accepted.
Bill me option is available only for US subscriptions.
Back issues are available. For subscription information,
e-mail subscriptions@codemag.com.

Subscribe online at
www.codemag.com

CODE Developer Magazine


6605 Cypresswood Drive, Ste 425, Spring, Texas 77379

codemag.com Managed Coder 73


MANAGED CODER

On Endings
For an industry that prides itself on its analytical ability and abstract mental processing, we often don’t do
a great job applying that mental skill to the most important element of the programmer’s tool chest—
that is, ourselves. “Keep to your dreams.” The posters and the memes are incessant. “Believe in yourself.”

The exhortations are obvious. “Never give up. the earbuds. For most of us, doing the mental partnerships? Or selling your share to your
Never quit. Never stop fighting.” math on the opportunity cost on actual currency partners and walking away grateful for the
is easy; doing that opportunity cost calculation experience?
I’ve been a software developer. I’ve been an on our time is much, much harder, and makes it • You can’t see how things can get any bet-
architect. I’ve been a startup founder (several that much easier to fall under the spell of moti- ter. The boss that hates you isn’t going
times), a manager, a university guest lecturer, vational posters or that whispered voice in the away any time soon. The coworkers you
a conference speaker, a corporate trainer, and a back of our heads. can’t stand are showing no signs of improv-
few other things to boot. Each one of these has in ing or being disciplined for their poor per-
common one thing: I’ve walked away from them How do you know when it’s time? formance. The company’s financials keep
at some point or another to try something new, tanking. Although nobody can predict the
something different. Sometimes the transition future, past performance usually is a pret-
felt like a natural progression (developer to ar- Walk Away When…. ty good indicator of what’s most likely to
chitect, for example), and sometimes it felt like No absolute formula exists that will work for all happen next, and sticking in it despite the
a wild step to the side (speaker and trainer to people, all the time, but here are a couple of evidence leading to continued downward
startup founder), but in each case, I had to look thoughts as to when walking away is actually trends isn’t perseverance, it’s insanity. If
in the mirror, think about what I was doing at the better for you than sticking with it. It’s time to you can’t formulate a concrete idea of how
moment, and say, “Yup, it’s time.” walk away when: things can get better, then they’re probably
not going to. And if that “concrete” idea of
In some cases, it was because there were other • Your health, mental, financial, or physi- things getting better involves winning the
things I wanted to do instead. Those situations cal, is taking a toll. At some point, the lottery—or something even more improb-
are the easy ones to grasp, because the thought cost involved in continuing in the current able—then you don’t really have a concrete
of doing the new thing makes it pretty easy to situation just doesn’t justify the return- idea.
think about leaving the old thing—it’s an A vs. on-investment. Professional athletes can • There’s nothing left to learn. Failure
B comparison that’s usually pretty easy to com- tell when it’s time to hang up the spikes teaches us a great deal about what we could
pare and contrast. Choosing to dump your current because their bodies simply don’t heal as do better next time, but at a certain point,
career as a host at a diner in order to pursue a fast as they used to, or they’ve “lost that there are just no more lessons left, only the
career as a software developer, for example, is a step.” Financial trends are relatively easy to feeling of being beat down. Again.
pretty open-and-shut case. But choosing to walk spot once you start looking at your finan- • You’re more concerned about the time/
away from twenty years as a software developer cial records and “do the math.” Mental toll energy/money invested already than
because you want to pursue opening your own is just as important to track—and is incred- what it will cost you to “stick it out.” The
restaurant—or coming to grips with the idea that ibly difficult to track. Ask people close to Sunk Cost Fallacy traps all of the best of us,
maybe it’s time to close down the restaurant— you to give you their honest feedback about and the only way to get past it is to start
those aren’t nearly as clear. your mental state: Do you seem happy? Are counting from here going forward—and not
you expressing frustration more often than include what all has already been spent. “I
Economists often refer to something called op- hope, or disappointment more often than gave five years of my life to that company!”
portunity cost, and the idea is simple but a little satisfaction? When we’re in the middle of is just focusing on the past, not the future:
abstract. Formally, it’s “the loss of potential gain a situation, it’s extremely hard to keep a Are you willing to give another five years?
from other alternatives when one alternative is clear eye on where and how we actually
chosen.” Consider $100 in your pocket. You can feel. But when you do finally figure out that Frequently, professional athletes, successful ac-
spend this $100 on a book, but then you can’t the spend is higher than the income, it’s tors, or other high-profile folks will announce
spend that same $100 on a set of headset ear- time to get out. their retirement and when asked why, will reply
buds. Spending the money on one alternative • You’re not sure what the end game looks with a simple, “It was time.” Like so many things
(the book) means that you lose the potential like. Everybody wants to stick with some- uttered in the public limelight, this simple phrase
gain you’d have gotten from the headset ear- thing until it’s successful, but what does usually masks hours and hours, if not weeks and
buds. And it’s not like you can avoid it—spending “success” really mean? What’s your target, months, of deep contemplation and reflection
the $100 on the headset earbuds means you lose your end goal? Is getting a promotion re- about their lives, position, and goals. If you’re
the potential gain from having bought the book! ally going to make the difference? For a feeling the same nibblings around the edges of
Either way, you’re losing something—and if you startup, for example, it’s easy to imagine your consciousness, but don’t want to face them,
choose to just put the $100 in the bank, you’re being the next Microsoft—but that almost
losing the potential gain from both the book and never happens. What about acquisition? Or (Continued on page 73)

74 Managed Coder codemag.com


BUILT
JUNE 3-5, 2020
McCormick Place
CHICAGO, IL

STRONGER
TOGETHER

With conference programs full of rich content and a vendor-neutral


expo hall floor – AEC Next, SPAR 3D and USIBD collide to offer
a diverse learning experience built to provide business solutions,
unparalleled networking and the latest technical advancements.

The future of AEC and 3D technology is here.

USE CODE SAVE100


for $100 off any conference pass
and/or free exhibit hall entry.

Register
Online @
aecnext.com or
spar3d.com/event

Produced by
Diversified
Communications

Autodesk
UR
GET YO R
OU
FREE H

TAKE
AN HOUR
ON US!
Does your team lack the technical knowledge or the resources to start new software development projects,
or keep existing projects moving forward? CODE Consulting has top-tier developers available to fill in
the technical skills and manpower gaps to make your projects successful. With in-depth experience in .NET,
.NET Core, web development, Azure, custom apps for iOS and Android and more, CODE Consulting can
get your software project back on track.

Contact us today for a free 1-hour consultation to see how we can help you succeed.

codemag.com/OneHourConsulting
832-717-4445 ext. 9 • info@codemag.com

You might also like