Google Search – Australia no longer “Feeling Lucky”

Aussies using Google have noticed they are caught in the middle of a recent conflict between Google, and the Australian Government over the newly proposed News Media Bargaining Code.   Aussie have a dependency on Google 93% of our online experiences begin with search engines. According to The Australian Bureau of Statistics, Google is by far the most […]

Read More

Pull Request Approved – Using GitHub as a CMS

Content Management Systems like WordPress, are often a popular choice when it comes to managing content, but have you ever considered using GitHub for the back-end? At SSW we are fans of GitHub, not just for source code but for web content too. I’ve discussed how we recently migrated our staff profiles from SharePoint to […]

Read More

I am on Cloud 9 – SSW has migrated to Dynamics 365 Sales cloud version 9

After months of planning, data trimming and delays (not helped by COVID-19!), I am happy to say that SSW has finally migrated our Dynamics from on-premises to the cloud. It has been well-received by all and the UX is much nicer. In addition, this is not the end of the journey – it is the start of a brave new world of awesome integrations leveraging Microsoft’s Common Data Service (CDS) along with a cornucopia of extra features and improvements over the on-premises Dynamics CRM that has held us in good stead since version 3 back in 2005.One of the biggest pains of not being in the cloud was that any CRM related work would need to be performed by one of our Dynamics developers…who are usually in very high demand by our clients, leaving little time to work on our internal systems. This slowed down development of some of our ground-breaking projects like SSW SophieBot™ and SSW TimePro™.
Happy SysAdmins
Now that we are online, thanks to CDS, we are already seeing quick adoption of Flow Power Automate and  Logic Apps by non-developers to automate processes. I loved seeing our SysAdmins using it in many scenarios from automating developer requests to automating their Domain Registrations – there was no need to involve a developer thanks to the low-code/no-code designer experience! ⭐(Note: Our SysAdmins do great work, and I will be thanking them next Friday on International SysAdmin Appreciation Day – will you be thanking yours?)
Speaking of our SysAdmins, the upgrade takes some load off their shoulders too.  Maintaining an on-premises solution requires more effort than you would expect. They were often doing something with the SQL, CRM and ADFS servers… not to mention having to manage the regular little updates.  In the cloud, updates are automatically rolled out for you on a frequent release cadence (on premises hasn’t had a major update for over a year!). 
If something does go wrong, it is much easier to get help from Microsoft support using Dynamics Online.  You can raise tickets via the web portal and in my (anecdotal) experience they often get back to you within a day.  Since all the servers are managed by Microsoft you do not need to worry about debugging any hardware issues, giving access to support people, etc.
One thorn!
One obvious change that comes with the fact that the server management is out of your hands is the restricted access to the SQL database that sits behind CRM. Of course this shouldn’t be an issue because you should *not* be doing any direct access. However at SSW we were quite naughty and had many reports coming from the database directly. Oooops – of course, this was only for reporting. We would never directly write to the database!  When you are running CRM on premises you have complete access to this database to read, write, or whatever else you want. 
There is good news regarding SQL! In the old days this meant that if you wanted a SQL database for reporting with CRM online, you would need to create a replica database sitting outside of CRM which is kept in sync with the CRM data.  Microsoft have recently opened up direct SQL reporting, which gives a live ‘read only’ SQL view of the data, and it works great!More info: https://rules.ssw.com.au/enable-sql-connect-to-the-common-data-service
Actually a 2nd thorn!
In terms of licencing, many of our clients noticed a change. Microsoft changed the Team Member licence by adding a 15 custom entity limit.  The Team Member licence has always been limited in its edit rights to standard Dynamics entities, however previously you could use it to edit an unlimited number of custom entities per Dynamics app.  Furthermore, previously the Account entity was editable with the Team Member licence, but this is no longer the case.  Changes in licencing like this, forced us to rework solutions for our customers to meet the new requirements. Although it ended up fine in almost all cases, there were a couple of customers that required the purchase of additional full Dynamics licences… which can really add up.
But wait… the final thorn!
One more thing to be aware of with CDS is the space!  I didn’t initially understand that the space you get, is consumed by the default CDS environment entities.  When you purchase Dynamics, you get 10GB of database capacity plus an additional 250MB per user licence – seems like heaps. Right?What I didn’t factor in is that each environment (test, staging and production) can consume several GB of this database capacity before you even put any data in! Furthermore it is impossible to delete since it is ‘behind the scenes’.  The additional storage is also extremely expensive at $55 AUD per GB/month ($660 AUD per GB/year). 
Figure: After creating a new environment you notice that your database usage is 3.5 GB and you haven’t even put in any data yet! Looking at the top 8 storage hogs by size, I see not one is a user table, like account, contact, activity etc. Each one of those GB is $55 AUD per month 
In conclusion
Overall I am super happy to be on the cloud. It’s a big step forward and we should have done it sooner, but I didn’t want to delete anything! Our CRM journey continues as there are several features only available online which we can now take advantage of:
the Unified Interface changes
the marketing module, field service module and more
the ability to embed Canvas PowerApps and Power BI reports into CRM forms and
a much improved email template editor
I’m looking forward to using it all!

Read More

Connecting Through Video – How To Engage Customers

Last month I talked about how easy it is to work from home, but to work from home effectively is hard. Likewise, making a video can be easy, but *really connecting* with your audience via video is hard. This is especially true for business videos. There is so much content that it is easy for people to glaze over your video and click away!At SSW we put a lot of effort into working out the best way to make business and technical videos. It’s been a super enjoyable journey and I’ve been learning and growing SSW TV for 11 years.
So how do you *really connect* with your viewers?
Tips:
#1. Quality: since the whole world is making videos now, not just the professionals, the only way to counter this massive increase in quantity, is to make *quality*. Today there is a tremendous range, from very poor, up to excellent quality. It is incredible to see some awesome quality unboxing videos, verses some shockingly poor business videos which can do a disservice to a company.
#2. Keep it light & consumable: many of us are reading news via social media, than from traditional sources. This means that unless you make a video that your friends are likely to share, no one will see it. BTW Australia is particularly susceptible to this problem, as we are one of the ‘leading’ countries in the world who consume their news mostly via social media.
Figure: Look at Australia, almost half (48%) of Australians read their news via light sources e.g. social media, so you can conclude that it is pretty important to make a video that is engaging and therefore shareable… and don’t make it too heavy obviously!Source: Digital News Report: Australia 2019
#3. Size matters: we are seeing the growth of multiple versions of each video – the 1 min version + the 10 min version for different contexts. You can use the 1 minute version for Twitter, and the 10 minute version for Facebook. See the example below of how an SSW TV NDC presentation that is 10 minutes long, can be trimmed to a 1 minute version that is more Twitter friendly.

#4. The script: it’s the same as building software, if you don’t plan, you plan to fail. Good storytelling comes from a good script. Once you have a good script, you can then focus on giving an excellent delivery.
#5. The editing: again it’s the same as software, if it’s a busy UI, it feels unfriendly. If it’s a complicated video, it is non engaging. Editors can help with this by following Richard Mayer’s “Multimedia principles,” and tighten up the video to make it more effective. E.g. People learn better when extraneous words, pictures and sounds are excluded rather than included. https://mylove4learning.com/richard-mayer-on-multimedia-learning/
#6. The cinematography: the importance of good lighting, framing, composition and sound cannot be overstated. The camera and the crew should disappear so that the only thing the viewers are focused on is the content.
#7. The Intro: getting the first 7 seconds right is critical, and the person who says it best is Geoff Anderson…

If you want to capture the attention of your audience with your video, you need to do it in the first fifteen seconds or less. People will visit a website for up to 7 seconds before deciding if they’ll hang around to find out more. Video can hold them for a bit longer – but not much longer. There’s a click happy finger out there looking for a reason to find a new video to watch. All of your video needs to be engaging but the first few seconds are critical. It needs to set the tone, show the style and cut to the chase. 
Chapter 1, Geoff Anderson “Shoot me now: making videos to boost business”  https://geoffanderson.com.au/shoot-me-now/
To see the above tips in action:
[embedded content]
Video: An example of a corporate video showing the team members in a great light. These team members are not actors, but with good direction, they come across as authentic and captivating. This video gets a lot of information across in a small amount of time. Most successful corporate videos are made by sitting down with the stakeholders and crafting a good script.

Our SSW TV team make awesome videos so get in touch if you’d like some help. We have guys on the ground in Sydney, Melbourne and Brisbane: https://www.ssw.com.au/ssw/Consulting/Video-Production
Ulysses Maclaren
Bonus – Interviewing Experts
Figure: Connecting with the interviewee and moving into the interview content without stating the interview has started – have a giggle.
#8. Warm up your subject: one type of video we really like to do at SSW is interviews, in person or remote. Even before lock-down we were recording people from all over that world. The lessons learnt there have been valuable, and apply to the current situation we all find ourselves in.Just like real life we analyse and understand people’s feelings and emotions through their body language. The aim of a good interviewer should be to make the interviewee feel as comfortable as possible; any signs of discomfort are visible through facial expressions and a person’s engagement (or lack of engagement).To make someone comfortable, have a light-hearted conversation with the interviewee and really connect with them. To do this, do not state the start point of an interview. Discuss normal conversational topics with the interviewee, and naturally start asking questions that relate to the interview. The aim is for the interviewee to not notice that the interview has even started. You’ll be amazed at how much of a difference this makes!
#9. Introduce the interviewee yourself: it’s more thoughtful to introduce someone yourself, and not to rely on the interviewee to explain who they are. You should know your subject, and give them a nice warm welcome. It’s not natural for someone to sprout their own biography (outside of a presentation), see Joe Rogan’s introduction for his guests.Bad Example:Interviewer: “Hello and welcome to the show, I have here Jason. Jason, please tell me about yourself.”Good Example:Interviewer: “Hello and welcome to the show, today we have Jason Taylor. Jason is one of the people who basically wrote the book on Clean Architecture and is currently doing many rounds of presenting all over the world, most recently at NDC. He is soon to release a new book which I have here, and it is awesome. Hello Jason welcome to the show.”
[embedded content]
Video: Here is an example of Marlon doing a nice intro of John Sonmez (from 0:20).
Summary
I hope these tips help you make better videos, and if you would like to know more you can read SSW’s Rules to Better Videos: https://rules.ssw.com.au/rules-to-better-video-recording

Read More

Hardcoding. Have your cake and eat it

2020-06-01CODING ·SOLID Principles

One of the core principles of software that is drummed into new developers is ‘Don’t Hardcode anything’. What if I told you that it’s OK to hardcode things? What if I told you that in some circumstances hardcoding is the RIGHT way to proceed?.As a junior developer, one of the key principles that were drummed into me was that hardcoding values is a BAD thing (amongst many other principles). But then more often than not, the pressures of deadlines, project managers and product owners don’t afford us the luxury of building an engineered solution the first time around. So we revert to simply hardcoding just to keep everyone happy and deliver a feature. What no one ever mentions is that there are two ways to hardcode values: the RIGHT way and the WRONG way.
I’ve seen developers new in their career, and even some more experienced fall for this trap. This scenario can play out in many different ways, perhaps it’s a Proof of Concept that “will just get thrown away”. Between you and me, rarely is code simply throw away, I’ve heard of too many POC’s that find their way into production.
Put simply, If somethings worth doing its worth doing right. Now, I’m not advocating wasting time implementing an over-engineered solution to prove a concept, or when time constraints (and PMs) don’t allow. What I am saying though is that when done correctly, we can have our cake and eat it too.
The WRONG way
Consider the following scenario: A junior developer has been tasked to implement a shipping cost calculator. Because of the time constraints, and the small target market the Product Owner is insisting that that solution must be simple, and hardcoding is fine, because “we can throw it away and do it properly when we have time”.
Being a junior, and somewhat naive developer they go ahead and implement the solution as follows:

public class ShippingService
{
//As per requirements from Product Owner, Hardcoding countries here, as
//These won’t change anytime soon, and we don’t have time to create a new database,
//and service and the added maintenance overhead.
public Dictionary countries = new Dictionary
{
{“au”,15M},
{“us”, 10M}
};

public decimal CalculateShipping(string country)
{
if (countries.TryGetValue(country.ToLower(), out var cost))
{
return cost;
}
throw new Exception(“Country not implemented yet”);
}
}

Clearly, the developer knows this isn’t the right thing to do, so they spent more time writing a comment justifying their actions… Now, what they don’t realise is that: a. The sales team has sold this feature to another 10 regions b. The Product Owner has identified another 10 different usages for country data, and not all of them are in the shipping service. Oh, and they’ll only tell you about them 1 at a time, over the next few months, to not overwhelm you. c. The backlog is so jam-packed there won’t be any time to go back and refactor any of the Country data anytime soon. Especially when the countries dictionary is so heavily utilised.
The RIGHT way
Luckily a more seasoned developer has had a chance to review the pull-request and offers the following solution:

public class Country
{
public string Name {get;set;}
public decimal ShippingRate {get;set;}
}

public interface ICountryData
{
Country GetCountryByCode(string code);
}

public class CountryData: ICountryData
{
//Hardcoded for now, Ideally provided by database
public Dictionary countries = new Dictionary
{
{“au”,new Country{Name = “Australia”, ShippingRate=15M}},
{“us”,new Country{Name = “United States”, ShippingRate=10M}}
};

public Country GetCountryByCode(string code)
{
if (countries.TryGetValue(code, out var country))
{
return country;
}
return null;
}
}

public class ShippingService
{
private ICountryData _countryData;
public ShippingService(ICountryData countryData)
{
_countryData = countryData;
}

public decimal CalculateShipping(string country)
{
var result = _countryData.GetCountryByCode(country);
if (result == null)
{
return result.ShippingRate;
}
throw new Exception(“Country not implemented yet”);
}
}

Notice that this extra work doesn’t cost much more to write. It doesn’t avoid the hardcoding. It doesn’t worry about databases or external dependencies. It just does the job, in a more ideal way.
Why is this a better solution
Adhering more closely to the SOLID principles we are working toward a more complete solution, as opposed to just solving today’s problem.
We are adhering to the Single Responsibility Principle, whereby the Shipping service isn’t concerned about the storage of country data.
We use the Interface Segregation Principle, along with Dependency Inversion Principle for the ‘ICountryData’ so that at any point in the future (when the budget allows) replacing the implementation won’t affect any of the calling code.
Importantly, the ICountryData interface, and even the Country class, aren’t fully defined just yet. That’s OK. No doubt these contracts will grow and evolve as the system grows. At least now we have somewhere to add this information.
Conclusion
When used in this fashion, hardcoding data can aid in the rapid prototyping of very complex systems. Instead of spending time and effort working on complex algorithms, and storage mechanisms etc, we should be looking to abstract out the complexity behind an interface and hardcode the simplest results. This way, we can move on with the rest of the system, without being blocked by some complexity that is not part of our immediate concern. Kick the can down the road, so to speak.

Read More

Working from home – romance or drama?

Wow. Hasn’t this been the world’s largest ‘working from home’ experiment? Developers working remotely or from home were quite common in our software industry even before the Covid-19 lockdown. At SSW, I’ve always been reluctant to do more than minimal work from home, for a few reasons;   I believe co-located Scrum Teams are better
It’s a lot harder to give your clients consistency and continuity: https://rules.ssw.com.au/do-you-understand-the-value-of-consistency 
I put a lot of energy goes into improving people’s presentation skills, and that is much easier to do in person
I’ve put a lot of time and effort into creating a cool stimulating working environment, and a culture that encourages cumulative brain power
Figure: Working together is always better, we have a great workplace with a lot of cool tech, sit-down stand-up workstations and a great vibe! The feedback from the developers about our office is really awesome (we have about 50 at SSW) Figure: The SSW Chapel is set up for recording presentations, our User Group, and training. Capacity has been paired down from 100 before Coronavirus, to about 10 for social distancing
Due to this lock-down, we’ve discovered that you can remotely simulate some of these things, with a little work.The most important thing, is to have good equipment and a good set up, with good quality sound, front lighting, dressed for work and video positioning at eye level… you know all of the basic stuff. It all helps to kick off a good meeting with your team/client. If you’re interested in how we do it, you can see our recommendations at SSW’s Rules to Better Remote Work. 

Most people at SSW have really enjoyed working from home. There’s no commute, or forgetting your lunch! Out of 50 developers, 44 answered my Microsoft Forms survey on their Coronavirus work from home experience so far. See some of the results below:
Figure: Some of the more interesting stats from my Microsoft Forms survey
Warning: Any ‘work from home’ study done during Cornonavirus times, when you can’t visit your friends and the pubs and restaurants are closed, is *not* going to be representative of a normal work form home survey, done during normal times when you have all of the normal social competition.Working from home should be giving people a better work-life balance, but if anything, it appears people have been working harder and doing a lot of extra hours. Twitter is full of people with stories of long hours, crazy homeschooling experiences, and Zoom/Teams fatigue.

If you’re working from home, and not enjoying it not, are any of these your reasons?
An increased number of video calls that require a lot of concentration  
Bad quality video calls
Unprepared people who start with ‘can you hear me?,’ ‘is this video clear?,’ who then forget to mute and then incredibly… start talking whilst still muted!
Distracted people due to many things, e.g. children, texts, other calls, dogs barking etc.
Your workday blending into your home life – blurred boundaries between home and work 
Not having a very good set-up. How I miss my 3 screens….  
Burnt out – feeling less and less productive 
Doing less exercise and eating worse
The Solution
Whether you’re in it for the long hall, or just having to do it for the next few weeks, SSW’s Jason Taylor has put together some practical ways to avoid the Work from Home burnout 🔥Jason talks about how to keep healthy and productive and how to give your clients a great experience! He’s been doing this for 10 years and has some great tips, watch his video below. 
[embedded content]
Important Takeaways from Jason
1. Stay connected – touch base every day, whether it be a Daily Scrum, or a daily catch up if your team doesn’t use Scrum.

2. Set a routine and be sure to stick to it, that includes getting dressed for work, and taking regular breaks.  
3. Communication – make sure you are always available in some way, this doesn’t mean dropping everything you are doing, it can be as simple as sending a message to say you’ll be with them as soon as you’re free. Then add this task to your TODO list while you remember.  
4. Stick to a routine – if you don’t get dressed for work, or prepare for your day, your work hours and personal hours are more likely to blend, which can lead to burn out. 
5. Take regular breaks! It will improve your productivity and general health 
6. Have a TODO list, it will make you feel more productive and help keep you focused!  
7. Have a dedicated workspace, it will help reduce distractions and try to set it up as ergonomically as possible. 
8. Do a Test Please on your equipment and environment – don’t be the person that starts a video call with “can you hear me/see me?” It will help give your team and clients a nice consistent experience, first time every time. 👀 ✔
Following these steps should help your WFH relationship be less drama and more romance. Check out SSW’s Rules to Better Remote Work for more awesome tips to help you keep you productive, professional and sane! 
Are you enjoying working from home? Fill out a copy of my Microsoft Form, I’d love to hear from you.

Read More

Using AppSettings in Blazor WebAssembly

While client-side Blazor technically isn’t yet stable, I love working with it more than other web front-end technologies. One significant hiccup I found while developing Cognitive Studio is having environment-sensitive configurations for the application.
I want my application to behave as an application that can live anywhere and is consistent with what we have in traditional .NET Core applications as much as possible.
My current solution is going the official route for AppSettings in Blazor introduced in 3.2 Preview 4 and updated to Blazor 3.2 Release Candidate.
Setup .NET Core Blazor app
Create appsettings.json and add it to wwwroot folder
Add any additional environment AppSettings like appsettings.Staging.json
Use Configuration
Blazor host already comes with configuration builder as part of WebAssemblyHostBuilder and gets built as well as registered when the host is built.
This means if you try to make your own IConfiguration, WebAssemblyHostBuilder.Build() will override it! Also, if you try to build configuration with WebAssemblyHostBuilder.Configuration.Build(), Blazor app will fail to bootstrap. I believe this is because appsettings.json is read via JS but JS interop isn’t read yet until Blazor app has successfully booted.
To solve this, when you want to use configuration, use lambda expression.

public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add(“app”);

ConfigureServices(builder.Services);

await builder.Build().RunAsync();
}

public static void ConfigureServices(IServiceCollection services)
{
// Example of loading a configuration as configuration isn’t available yet at this stage.
services.AddSingleton(provider = >
{
var config = provider.GetService();
return config.GetSection(“App”).Get();
});
}

You can also use the following code in Razor pages to access configuration directly.

@inject IConfiguration Configuration

Configure multiple environments
This part is about loading the correct AppSettings. The default appsettings.json is always downloaded, while the appsettings.*.json is downloaded based on the app’s environment.
Currently, the only way to set the Blazor WebAssembly environment is to return HTTP header blazor-environment when requesting blazor.boot.json. Custom HTTP headers are not a big problem if you use a web server to serve your application. In Azure WebApp you can use web.config and other platforms have ways to inject HTTP headers to requested files.
Sadly, GitHub Pages and Azure Blob Storage Websites don’t support custom HTTP Headers.
Yes, you can try to inject an HTTP header inside index.html with the following metadata:

This won’t work because the header needs to be set for blazor.boot.json!
Is to postpone loading Blazor (came with 3.2 Release Candidate) and inject headers in Blazor.start.
In wwwroot/index.html add:

const environmentName = ‘Staging’;
Blazor.start({
loadBootResource: function (type, name, defaultUri, integrity) {
// Adds a custom HTTP header to the outbound requests
// To retain the default integrity checking behavior, it’s necessary to pass through the ‘integrity’ parameter
return fetch(defaultUri, {
cache: ‘no-cache’,
integrity: integrity,
headers: { ‘blazor-environment’: environmentName }
});
}
});

Now all you have to do is to modify environmentName value on deployment and you’ll dynamically download the correct AppSettings! 😁

Special thanks to Steve Sanderson for finding a workaround for the switching environments problem. 🙂
Original issue: https://github.com/dotnet/aspnetcore/issues/20935
UPDATE 1: Added code for DI and accessing configuration.UPDATE 2: Updated how to inject headers in Blazor 3.2 Release Candidate.

Read More

Coronavirus – What we are doing at SSW

This weekend I saw Coogee Beach packed to the rafters with parties. I also saw that The Oaks Hotel in Neutral Bay and The Coogee Bay Hotel were full of people who are either oblivious or stupid.
Note: Sadly, the Australian numbers are now much worse than below explained by this .gif:

2 weeks ago I spoke to each SSW office individually via Microsoft Teams and gave the following advice to all SSW employees to navigate Coronavirus. I am sharing this – I hope it helps:

From: Adam Cogan
Hi SSWAll,
The COVID-19 numbers are increasing every day – it is time to be worried and make some changes. Today NSW is the worst state at 171 cases (more numbers below).
Let’s focus on staying healthy for now. We can navigate the upcoming business challenges after that.
Stay home!
Over the next 8 weeks stay at home as your first option.  The incubation period for COVID-19 is around 2-8 days. The next 8 weeks are the most critical time for people to stay at home. Note: The average incubation period is 5.2 days. (Source: Prevention and control plan of new coronavirus pneumonia (fourth edition) issued by the National Health Commission of China).
Be safe!
There are going to be asymptomatic carriers – people who are infected, contagious, and don’t know it.
Practice social distancing over the next 8 weeks – by then you will know most of the people who became infected because they will be sick. (However, some people will have it, but show no or little symptoms). At this time, it will be easier to avoid infected people. Wait for them to get better and we can neutralize the spread of the virus. 
We won’t be as lucky as SSW China!
No-one in SSW China got the disease. And I think we can say it is under control in Hangzhou. Only 2 cases in the last 24 days in Hangzhou (pop. 13 million). But they were hardcore at their isolation. In Australia, the govt is softer and Aussies are more cavalier. She’ll be right mate!
This is going to be rough. Don’t go on public transport, drink at bars, eat at restaurants, work out at gyms, etc. You likely will contract the virus and the number of oblivious asymptomatic carriers will grow at a nasty rate. The best thing you can do is wash your hands regularly and especially before eating… Oh and don’t touch your face.
I don’t believe we will be able to contain the disease in Australia. It will wreak havoc on everyone’s lives. Our medical system will not be able to keep up with the onslaught of cases. The economic catastrophe will grow as we have never seen.
Work from home!
If you have a home office with internet, and a good mic and camera then you can and should work from home. Check your background and do a test with a colleague that you look and sound great. Clients still come first and for some, this will be a tricky balance. I don’t think we have too many clients that do not understand the situation. If the clients are not cool about remote meetings, then talk to your SSW State Manager.
Stay home and you will help doctors!
My neighbor is a doctor… he has been working long hours testing 150 patients each day for Coronavirus…. for the last 3 weeks! Not one positive yet for him. However, he says he has been ignoring all his normal sick patients. He is exhausted and sad.
Think about what you can do to help others!
SSW is experienced and set up for remote working – not every business is. Technology can help people. Keep your eyes and ears open to businesses who have unproductive staff and let them know how you work and what software we use eg. Azure DevOps, Microsoft Teams, SugarLearning, etc.
Call any friends you know who have just started Work From Home. Test their mic and camera placement. On so many of my calls, I am discovering not many people are equipped well to WFH, nor know basic mic/camera placement tips. Help everyone you can.
Have fun too – E.g. I love the Wuhan Shake:
[embedded content]
The numbers
Last Friday, I send you the free lunch email with:

Today the updated data is:
NSW: 171 (2 deaths)
Victoria: 71
Queensland: 68
Hangzhou: 170 total cases 167 recovered 
And sadly the Economic Pandemic is just getting started:
Australian dollar dropped to a 12-year low of 61.1 US cents.
Australian Stock market plunged 9 percent to record the heaviest loss since the 1987 crashOuch!
-aAdam Cogan

Coronavirus protocol at SSW – Help us avoid any spread of the coronavirus at SSW
Before SSW
Working from home is preferred at this time.
If you are using public transport please avoid coming to SSW.
If you (or your partner) are sick, stay at home. Seek medical attention.
Avoid Public transport – it is one of the worst places to be during an epidemic as diseases can spread easily on planes, buses, and trains. Again Work From Home #WFH.
If you have been overseas, self-isolate for 14 days.
The new Coronavirus remains on plastics and stainless steel (surviving for up to 72 hours). If you have to go public, try to avoid directly touching the metallic surfaces e.g. elevator buttons, bus handrails, etc. More info https://www.medrxiv.org 
Be a watchdog and say something when people ignoring the pandemic situation we are facing eg. “Want to go to the pub?” Say “No let’s be responsible and have a beer over skype tomorrow”
If you have been in contact with someone with the virus please do not come to SSW. Email your SSW State Manager and Cc Adam
At SSW
If you must come to the office, please wash your hands for 20 seconds with soap + clean your phone. It is filthy.
Wash your hands before eating.
Dry your hands properly – it is just as important as washing them properly. Read Not Drying Hands Thoroughly After Washing Could Aid Bacterial Transfer
Avoid touching your face
No handshakes, hugging, etc. Go for the Wuhan Shake.
Face mask where you can – In China they are required to wear a face mask in public and in the office – seems to help them.
Turn off the central air-conditioning – again a Chinese recommendation
If you use the toilet in the bathroom please only flush with the seat down.
Please cough or sneeze only in your elbows, shirt or a tissue.
Ensure that after a cough or sneeze clean and disinfect the desk surface.
Please maintain a social distancing of 1.5 meters.
Thank you for your help and cooperation in this difficult time 😀
Hygiene Enhancements
I have already spoken to the Sydney, Melbourne, and Brisbane cleaners and they are all doing extra cleaning and disinfecting all knobs, etc.I forgot to include the fingerprint scanner until it was pointed out to me 🙂
Figure: 8 Steps of washing your hands ✔
Summary
COVID-19 (Coronavirus) is going to have big implications for all of us. For now please focus on the tips for hygiene + the social distancing rules. The next few months will be tough and scary. However, there will be good that comes of this too. Working from home will become more acceptable to our clients. This is going to be the largest work from home experiment the world has ever seen.
For March and April and likely beyond we are only going do SSW events online. Losing our in-person Superpowers training is painful. My daughter has just started university and as it now closed, her first 2 weeks already have been via online classes. SSW TV becomes even more important to us.
I think we have plenty of new data – a great A / B test if you will – and we will see what good the reduction of travel has done for our environment. I think we will lose some clients and gain others.
I know this is going to be a disruption to SSW and our customers. Stay strong and learn a lot!
-aAdam Cogan

Read More

Technology in a Pandemic – Helping Control Coronavirus

SSW China have been working closely with the District Government in China to develop an application that will help reduce the spread of Coronavirus. Split into two smaller apps, it has revolutionised reporting during this deadly outbreak.The Government called us during the Lunar New Year, and commissioned SSW to build this with absolute urgency. The 1st application, is a Quarantine Reporting System. Built in React and .NET Core, the application helps residents report their symptoms, apply for leave passes and gain government help and resources when they need it, without having to leave home. It means that they can self quarantine without being assessed and do not need to worry about going outside for supplies, which should drastically reduce the risk of others being infected.The 2nd application is a Government Service System that allows people who are returning to work to do so easily. There are many construction sites facing the scary task of re-opening as the pressure to return to work gets bigger. The construction industry is labour-intensive, and the workers are almost all migrants. In order to help control the epidemic and prevent the potential spread of the virus, the government has introduced strict regulations for the returning work population.
Figure: The Coronavirus App in action
In the past, the process has required individuals to submit paperwork, a *lot* of paperwork. It was labour-intensive, slow and frustrating for operators and staff. Now they can do everything in one place, online, with no paperwork to do. It has revolutionised the return to work system, making it so much easier for both employees and business owners.
The SSW China team have put in some crazy overtime (hundreds of hours in the last month) building this application but they are so proud of the results!
Lessons from China – Controlling the spread of Coronavirus
[embedded content]
Like many other offices in China, many of the SSW guys went back to their hometown to visit family for the Lunar New Year. When they returned back to SSW Hangzhou, they all had to go through a mandatory quarantine period, where they had to stay home and not go out for 14 days (some of them more depending on where they had been).
To make sure our team were protected, we gave them an extra week off, and a week to work from home. Developers are so lucky, these days we can work from anywhere! It meant we could continue to work for our main clients, even when many staff members were still in quarantine.
Some of the team have now been allowed to return to work at the SSW China office, but they have a crazy routine to follow in order to comply with the government rules and to help protect themselves from the virus. Check out their daily routine in this fun video by SSW Admin Sharon Du.
How is it affecting Australia?
Just as Australia started to recover from the devastating bushfires, we were hit by floods, and now, like 60 other countries around the world, we are dealing with the threat of Novel Coronavirus (COVID19).

People have been behaving very strangely, and it’s not because they have the virus. The panic of a potential quarantine has driven people to start stock piling long-life goods like pasta, canned veggies, hand sanitizer and toilet paper. Images from the great toilet paper shortage (there is no real shortage) has been trending on Twitter for weeks #ToiletPaperApocalypse.

Closure of Large Tech Events
Due to the rapid spread of Coronavirus, companies are becoming more and more nervous about running large events where huge numbers of people will congregate. It has already caused the cancellation of popular industry conferences, like Google’s Cloud Next in San Francisco, and Microsoft’s MVP Summit in the Seattle.Organisers have chosen to reduce the risk of infection by turning them into virtual events instead.

Microsoft cancels MVP Summit due to COVID-19 virus fears. The mid-March event will be a virtual-only one now: https://t.co/6ttwVLq4ad
— Mary Jo Foley (@maryjofoley) March 2, 2020

What you can do to protect yourself
You can choose to be as cautious as our SSW China team, (who are in the epicentre of the virus), or do more basic things to prevent infection. According to the World Heath Organisation, Coronaviruses typically cause respiratory symptoms, so they recommend that you adhere to:
normal basic hand hygiene practices, like hand washing with soap and water
respiratory hygiene such as covering your mouth with your elbow when you sneeze
wearing a face mask if unwell.
They break it down for you in this cool informative video:
[embedded content]
Stay safe everyone and remember to wash your hands and don’t hoard toilet paper!

Read More

EF Core Query Tags and Alternatives

When doing a performance review on client applications (and my friend’s apps), I often see issues related to EF Core and most devs don’t seem to notice them until they spiral out of control. When this happens, they don’t know how to find problematic queries and then link them back to the original code.
In this blog post, I’ll show you a couple of tricks on how to track your queries, so when you need to debug performance issues, you won’t have a problem finding the problematic SQL query as well the code that generates it. You can also skip to the end of the recommended approach.
I’ll assume that you have configured logging in your .NET Core application, but if you need instructions for that, go to ASP.NET Core 3.0 + Serilog. I recommend collecting the logs into Seq and/or Application Insights for later analysis.
Tagging Queries
If you use EF Core 2.2+, you can easily track your queries by tagging them with .TagWith().

var list = await _context.Tweets
.TagWith(“GetTweets”)
.ToListAsync(cancellationToken)
.ConfigureAwait(false);

This will add GetTweets into SQL statement, which can be seen in logs and even SQL Profiler.

— GetTweets

SELECT [t].[Id], [t].[CreatedUtc], [t].[Message], [t].[Username]
FROM [Tweets] AS [t]

Figure: We can see the tag as part of the query.

Query Tags are supported to any IQueryable. This includes methods like FromSqlRaw which are now being used to execute store procedures and views as long it inherits from IQueryable.
Sadly adding, updating and removing entities is not supported by Query Tags.
NOTE: For EF6 you can try to use this 3rd party Nuget package: EF6.TagWith
Log Scope
The second approach is to add Log Scope. This approach is great if .TagWith() isn’t available. This could be because you want to log inserts/updates/deletes, you’re running EF Core before version 2.2, legacy EF or even if you don’t have direct access to the queries (like Microsoft Identity).

using (_logger.BeginScope(new Dictionary { { “EFQueries”, “GetTweets” } }))
{
return await _context.Tweets
.ToListAsync(ct)
.ConfigureAwait(false);
}

In this example, I’ll show you how you can indirectly log SQL statements generated by EF Core. To demonstrate that, we’ll need to get an instance of ILogger and then we’ll create a new Log Scope, which propagates to all logs inside that context.

public async Task InsertTweet(string username, string message, CancellationToken ct = default)
{
// This can optionally be in the bellow log scope but is not necessary.
// The tweet is going to be added into SQL DB when `.SaveChanges` is called.
_context.Tweets.Add(new Tweet
{
Username = username,
Message = message
});

using (_logger.BeginScope(new Dictionary { { “EFQueries”, “InsertTweet” } }))
{
// This will make SQL queries to save data into DB.
await _context.SaveChangesAsync(ct).ConfigureAwait(false);
}
}

Figure: Add tweet by adding it to Tweets table.

public async Task InsertTweet(string username, string message, CancellationToken ct = default)
{
using (_logger.BeginScope(new Dictionary { { “EFQueries”, “InsertTweetStoreProc” } }))
{
InsertTweetInternal(username, message);
}
}

private async Task InsertTweetInternal(string username, string message)
{
// This query can also be outside this class and it would still be logged with the “EFQueries” scope.
_ = _context.Tweets
.FromSqlRaw(
“InsertTweet @Username, @Message”,
new SqlParameter(“Username”, username),
new SqlParameter(“Message”, message))
// A hack to make STORE PROC work when they don’t return anything.
.AsNoTracking()
.Select(x = > new { })
.AsEnumerable()
.FirstOrDefault();
}

Figure: Insert Tweets with store procedure.

The above query might get lost if you have a lot of different queries, but by adding a Log Scope, we can search in your preferred rich logger aggregator like Seq or Application Insights for “InsertTweetStoreProc” in property “EFQueries”.
This way, all queries are searchable based on context, find rogue queries and separate your queries from 3rd party queries. Now you can better focus on what queries to optimize or find original code that ran that query.
Recommended approach
Depending on the project, Log Scope might be a better approach since now you can track every SQL query (and other logs) the same way. Use Log Scopes when you know that SQL Server is going to be a problem or visibility is more critical then compact code.

using (_logger.EFQueryScope(“GetTweetsLog”))
{
return await _context.Tweets
.TagWith(“GetTweets + LogContext”)
.ToListAsync(ct)
.ConfigureAwait(false);
}

Small utility for easier logging:

public static class EFCoreLoggingUtils
{
public static IDisposable EFQueryScope(this ILogger logger, string queryScopeName)
{
return logger.BeginScope(new Dictionary { { “EFQueries”, queryScopeName } });
}

public static IDisposable EFQueryScope(this ILogger logger, string queryScopeName)
{
return logger.BeginScope(new Dictionary { { “EFQueries”, queryScopeName } });
}
}

Figure: Logs in Seq with Query Tags and Log Scopes.
In Seq and Application Insights you can find all queries with the following filter SourceContext = “Microsoft.EntityFrameworkCore.Database.Command”. You can then do further filtering based on Log Scope by filtering EFQueries.
You can find source code here: https://github.com/jernejk/EfCoreSamples.Logging

Read More