OdeToCode IC Logo

Think Twice Before Returning null

Wednesday, August 7, 2019 by K. Scott Allen

Let’s say you are working in the kitchen and preparing a five-course meal. A five-course meal is a considerable amount of work, but fortunately, you have an assistant who can help you with the mise en place. You’ve asked your assistant to cube some Russet potatoes, julienne some baby carrots, and dice some red onions. After 15 minutes of working, you check on your assistant’s progress and ...

Kitchen disaster

What a disaster! You have diced onions to cook with, but you’ve also got a mess to clean up.

This is how I feel when I use a method with the following inside:

return null

I’m seeing thousands of return null statements in recent code reviews. Yes, I know you’ll find my fingerprints on some of that code, but as my mom used to say: "live and learn".

Returning null Creates More Work

An ideal function, like an assistant cook, will encapsulate work and produce something useful. A function that returns a null reference achieves neither goal. Returning null is like throwing a time bomb into the software. Other code must a guard against null with if and else statements. These extra statements add more complexity to the software. The alternative is to allow null to crash the program with exceptions. Both scenarios are bad.

What Are the Alternatives?

Before throwing in a return null statement, or using LINQ operators like FirstOrDefault, consider some of these other options.

Throw an Exception

In some scenarios the right thing to do is to throw an exception. Throwing is the right approach when null represents an unrecoverable failure.

For example, imagine calling a helper method that gives you a database connection string. Imagine the method doesn’t find the connection string, so the method gives up and returns null. Your software doesn’t function without a database, so other developers write code that assumes a connection string is always in place. The code will try to establish connections using null connection strings. Eventually, some component is going to fail with a null reference exception or null argument exception and give us a stack trace that doesn’t point to the real problem.

Instead of returning null, the method should throw an exception with an explicit message like "Could not find a connection string named 'PatientDb'". Not only does the software fail fast, but the error message is easier to diagnose compared to the common null reference exception.

Throwing is not always the right option, however. Consider the case where a user is searching for a specific patient using an identifier. A method to execute the search has to consider the possibility that a user is searching with a bad or obsolete identifier, and not every search will find a patient. In this scenario it might be better to return null than throw an exception. But, there are other options, too.

Return a Default Value

Finding a sensible and safe default value works in some scenarios. For example, imagine a helper method to fetch the claims for a given user. What should the method do when no claims are found? Instead of returning null and forcing every caller to guard against a null collection of claims, consider returning an empty collection of claims.

private static readonly IReadOnlyDictionary<string, string> EmptyClaims = new Dictionary<string, string>();

public IReadOnlyDictionary<string, string> FindClaims(int userId)
{
    /*
     * Find claims from somewhere, or ...
     */


     // when no claims are found . . .
     return EmptyClaims;
}

If callers only use ContainsKey or TryGetValue to make authorization decisions, the empty claims collection works well. There are no claims in the empty collection, so the software will never authorize the user. Even better, the code doesn’t need to guard against a null reference.

Think of all the complexity you've removed from the rest of the software! Future generations who work on the code will praise you and build ornate shrines in your honor.

Return a Null Object

The null object pattern has been around for a long time because the pattern is successful at reducing complexity and making software easier to read and write. Imagine a method that needs to return the current user in the system, but the method can’t identify the user. Perhaps the method can’t identify the user because the user is anonymous, and not being able to find the user is an expected condition. We shouldn’t handle an expected condition using exceptions.

Another option is to use null to represent an unknown user, but returning null is lazy. In case you missed the opening paragraphs, returning null is like telling your callers "I’m not only giving up, but I’m going to stick you with a dangerous value, so handle with care, and good luck!". Future generations who work on the code will curse you and burn you in effigy.

The null object pattern solves the problem by returning a real object reference, and the real object contains some safe defaults. We don’t want an unidentified user to gain access to admin functionality, or somehow slip through permission checks, so we create a version of the user that will fail all permission checks and not display a name, but at the same time no code needs to guard against null and introduce if else checks everywhere.

There are a number of different approaches you can use to design null objects, but remember the goal is to build an object with safe defaults. Here’s an example. Let’s start with a User type.

public class User
{
    public User(string name, IReadOnlyDictionary<string, string> claims)
    {
        Name = name;
        Claims = claims;
    }

    public string Name { get; protected set; }
    public IReadOnlyDictionary<string, string> Claims { get; protected set; }
    public bool IsAdmin { get; }
}

Now we can create an instance of User that contains safe defaults, like an empty claims dictionary so the IsAdmin helper (which presumably looks into Claims, will return false). One way to define the class is to use inheritance, like so:

public class NullUser : User
{
    public NullUser() : base(string.Empty, EmptyClaims)
    {

    }

    private static readonly IReadOnlyDictionary<string, string> EmptyClaims = new Dictionary<string, string>();
}

Now we can write a method that always return a safe value.

private static readonly NullUser nullUser = new NullUser();

 User GetCurrentUser()
 {
     // if user not found :
     return nullUser;
 }

If we start thinking about alternatives to null today, we'll be better set to handle the future.

The Future Is Undoubtedly Going to use Non-nullable Reference Types

There is a new feature coming with version 8 of the C# compiler that will help us avoid nulls and all the problems they bring. The feature is non-nullable reference types. I expect most teams to aggressively adopt C# 8 after the release later this year, at least for new code. You can find many examples of the new feature in Microsoft docs and blogs, but the idea is to tell the C# compiler if a null value is allowed, or not, in each variable. The C# compiler can aggressively check code to make sure non-nullable reference types do not receive a null value. Using these types should give us simpler code, and force us to think before adding a return null.

Summary

Ten years ago, Tony Hoare apologized for inventing null, calling the null reference a billion dollar mistake. Let's see if we can avoid using his mistake!

Remember the Principal of Least Privilege When Upgrading Those Older ASP.NET Applications

Wednesday, July 31, 2019 by K. Scott Allen

When I started developing with ASP.NET many years ago, we used two tools on a regular basis. We used Visual Studio to write code for applications, and Internet Information Services (IIS) to host the applications.

IIS runs as a privileged service in Windows, meaning IIS has access to resources, APIs, and data structures on a machine that a normal user couldn’t read or write. The extra privilege afforded to IIS works well when you want to run an application in production and execute as fast as possible, but is a problem when you want to develop, test, or debug an application. Debugging, for example, requires an intimate relationship between two processes where the debugger controls the execution and the memory space of the debugee. Attaching a debugger to a privileged process like IIS isn’t something ordinary users should be able to do.

Debugging a privileged process requires … privileges, which is why Visual Studio requires us to run as an Administrator if an ASP.NET project uses IIS for hosting. Running a development tool as the machine administrator violates the principle of least privilege, which is a principle we should all value in these dark days of phishing attacks, data breaches, and Snapchat.

Microsoft released IIS Express in 2010 to help us develop, test, and debug applications without elevating into the administrator role. The express version of IIS has most of the key features that IIS includes for hosting and running web applications. But, instead of running as a privileged service, IIS express runs as a normal process using the same identity as the developer.

A few older projects I've been in lately still require IIS, which requires running as an Administrator. This is certainly not a situation you want for new applications, and it should be part of a migration plan when working with older applications. In Visual Studio you can right-click on an ASP.NET project and go to the web properties to configure a project for using IIS Express.

VS Web Properties

Using IIS Express for developing with ASP.NET will help us obey the principle of least privilege but might present some other difficulties. IIS Express works best with monolithic applications. We’ll need some extra setup for systems composed of multiple services, processes, and applications. Since Express doesn’t run as a service, Visual Studio has to launch your applications on demand. If you want to have multiple applications and services running concurrently without launching Visual Studio and opening a project for each component, than the following tips might help.

  1. You can still configure IIS with websites pointing to all the components in a system. You’ll only be able to debug the component running in Express with Visual Studio, but at least the other services are alive and responding.

  2. You can use the command line to run Express and launch as many applications and services as you need (see https://docs.microsoft.com/en-us/iis/extensions/using-iis-express/running-iis-express-from-the-command-line).

  3. For more complicated scenarios, look into using containers and container orchestration.

So while there might be some extra work involved, not running as an administrator gives you a better security profile, and helps to obey the principle of least privilege.

Advanced Azure App Service Articles and Videos

Friday, July 26, 2019 by K. Scott Allen

Over the last few months I've put some work into explaining Azure App Services.

At Petri.com

Demystifying Azure App Services is a look behind the abstraction of Azure App Services.

Demystifying Azure App Services Plans gets into the details of what makes an App Service Plan.

Demystifying Azure App Services – Diagnostics and Telemetry looks at some of the gems in App Services smart and opinionated diagnostics.

At NDC

Here's a recording of my App Service talk at NDC Oslo.

I hope you enjoy the material!

Talk Ideas for 2020

Wednesday, June 26, 2019 by K. Scott Allen

After a 12-month break from developer conferences, I'm looking forward to working with a small handful of conferences next year. I've been kicking around some ideas for topics I’d like to talk about, and I'm sharing those ideas because thoughts and feedback are always appreciated!

An Architects Guide to Building Cloud Native Solutions in Azure

One of the challenges you’ll face when building applications in the cloud is in choosing the best technologies for your solution. In this session we’ll take a broad look at the technologies, services, and infrastructure available in Azure while drilling into the vital details you need to make decisions. What’s the best host for my container-based solution? Should I place my data into a data lake, a data warehouse, or a simple blob container? What’s the essential difference between a message queue and an event hub? We’ll answer these questions while also covering topics like security, identity, governance and compliance.

Into the Sky

Apache Spark for .NET Developers

Big data meets .NET with Apache Spark, the analytics engine for large-scale data processing. If you are a .NET developer and you need to create an ETL process for high volumes of data, or process large streams of data in real time, or train machine learning models against a big data set, or explore big data sets with exploratory queries, then Apache Spark is a technology you should know about. Once we’ve seen how to setup an Apache Spark cluster and worked with the shell, we’ll dive into the .NET bindings for Spark and see how to query and analyze data using C#, F#, and SQL. We’ll also be looking at Azure’s DataBricks platform to work with Spark in a managed environment.

Around the Corner

What .NET Core Developers Should Know about MSBuild

If you’ve ever wondered what makes MSBuild work, or if you’ve ever needed to tweak the XML in a project file to allow your software to compile, then this session is for you. We’ll start by learning about the fundamental concepts in MSBuild, concepts like tasks, properties, and conditionals. We’ll then move into the details of build targets that drive most of today’s builds. This talk is based on years of experience in being the person who everyone uses to debug builds, so there will be no shortage of tips and tricks for managing and debugging your builds.

A Seat at the Table

Five Lessons Learned as the CTO

Leadership skills come naturally for some people, but for the rest of us we need to figure out leadership as we go along. If you are thinking of making the jump from being a technical contributor, or have your sights set for the chief technical position, this session will give you some insight and lessons learned from experiences on the job.

Tapestry

Questions from the NDC Oslo Panel Discussion on the Future of .NET

Monday, June 24, 2019 by K. Scott Allen

At NDC Olso I was part of a panel discussion with Julie Lerman, David Fowl er, Damian Edwards, and Bryan Hogan. Here are my stream of consciousness answers for some of the questions presented to the panelists. Not all the questions were directed to me, but I jotted down some thoughts nonetheless.

NDC Oslo Show Floor

What are you most excited about with .NET Core 3?

This might sound odd, but I’m excited about WPF and Windows Forms. It’s not that I want to go out and write a new application using WinForms. But, I have a WinForms application that is still in production and is old enough to graduate from high school. I feel good knowing that Microsoft recognizes the importance of these older frameworks and the importance of writing desktop applications. For some scenarios, desktop applications are easier to build than web applications, and for the first time in more than 5 years I feel like .NET supports the desktop.

I’m also excited about gRPC services in ASP.NET Core. I think the enterprise struggles with the alternatives to WCF and SOAP. REST and hypermedia work well for some services and applications, but there are many scenarios where you need to bang out a distributed service and don’t need the overhead of perfectly decoupled components. In other words, HTTP and JSON are great, but the old days of “Add Service Reference” aren’t as bad as many people make them out to be. Like it or not, SOAP and WS-* protocols still perform significant amounts of work in today’s world. I believe gPRC can be a better SOAP.

NDC Oslo Panel Discussion on the Future of .NET

What do you think of performance improvements in .NET Core 3?

My favorite new API is Math.FusedMultiplyAdd. The operation sounds like something you might need in the software for a thermonuclear simulator. It’s fast, and it’s accurate! Be careful!

Where Do You See the Entity Framework Going?

I think EF needs to expand its reach far beyond relational databases. I know EF Core 3 is going to support CosmosDB, but its taking a long time to get there, and I already have good abstractions I can use in the Cosmos DB SDK, so I don’t need EF there.

It’s funny, ten years ago I considered relational databases to be the only way to store data. Then I started using MongoDB in real applications and I started to see all the alternatives. Today, I think of relational databases as specialized high-end storage for specific use cases. The bulk of my data, in terms of both volume and processing, lives outside of a SQL database. The data is in blob storage, and in data lakes, and is streaming through event grids, and getting crunched in Apache Spark clusters. That’s where I need help with data.

I think the best thing EF could do moving forward is to split into two frameworks. One part of the framework could map data from CSV files and JSON payloads into CLR objects as quickly as possible. But, I don’t want just an object mapper in the AutoMapper sense, I also want something similar to an F# type provider for C#. I want to point to data in an Azure data lake or an event grid stream and then express my computations using strong types.

The other part of the framework could focus on sending commands and queries to a remote data source for processing. Currently, EF translates LINQ expressions into SQL, but I think we need to give up on the dream of LINQ to everything. It takes too long for EF to support new databases, like ComosDB. It takes EF too long to support common features of a single database, like views and stored procedures in SQL. What we need is an EF that allows developers to use native data processing languages in straightforward fashion. Give me an elegant way to embed SQL statements in my code. SQL is everywhere! SQL is a language supported by SQL Server, by Cosmos DB, by Apache Spark, and in the future even blob storage in Azure. I need to take advantage of as many SQL features as I can without being limited by what can be expressed in C#, and then I need to execute the SQL and map results into objects.

In short, I want better language interop and forget about abstracting heterogeneous data sources behind C# expressions.

NDC Oslo Panel Discussion on the Future of .NET

Do you worry that changes in .NET could leave people behind?

I do worry. I’m worried about people getting left behind, and I’m worrying about people getting confused and giving up. A couple of years ago I made a deliberate move away from front-end development because I felt the pace of change was unhealthy. It felt like everything was changing, but not getting better. The improvements were small and not worth the cost of keeping up to date. I always use webpack 4 as a specific example. There were many breaking changes between version 4 and version 3. For example, loaders were removed and replaced by rules. From what I could tell, rules don’t offer any features beyond loaders, but everyone moving from webpack 3 to webpack 4 starts with a broken webpack build because of the change, and they need to research the change and find out how to update their webpack configuration.

I think .NET and the C# language are both changing, and I do believe they are moving forward, they are improving, and they are not just changing to make a change. But, I do worry that Microsoft doesn’t keep backward compatibility as a priority anymore. I know that backward compatibility can be an albatross and there’s been a lot of bad decisions made in the name of backward compatibility, but I also know I’m not pushing my team to update their ASP.NET Core 1.1 applications because of all the breaking changes in moving to 2.2. We’ll need to move eventually, but there’s nothing forcing us to move today except for the end of support coming in a few weeks. We’ll have to set aside a couple days to make the move and figure out the new package names, the new extension method namespaces, the new name for the web host builder, and how to configure the new authentication and authorization services and middleware. Then we have to run some tests and make sure we have no regressions in performance, features, or security. Upgrading is not just setting a version property in a project file, sometimes you need to learn about the philosophy changes in the framework.

Do you find companies are still reluctant to adopt Entity Framework?

Yes, I do. Just last month I was working with a development team that made it clear from the start that this team uses a DBA, and the DBA is going to be solely responsible for writing all SQL queries for the database.

It is a reasonable decision to avoid the Entity Framework, and there are many reasons you can use to justify this decision. I only ask teams to avoid EF for the right reasons. Don’t avoid EF because you think EF is insecure. I’d bet EF does a better job avoiding SQL injection attacks than hand rolled code. Don’t avoid EF because you think EF will be slow, there are many scenarios where EF is fast enough.

If you could rewrite .NET entirely, what would you change?

If .NET includes the C# language, too, the first thing I’d rip out and redo is async and await. We need async programming models, but the current solution is fragile and frustrating. I don't like the Async postfix convention in my codebase. I don’t want to see ConfigureAwait in my library code. I don’t want to worry about running sync code over async code or async code over sync code. We need better operability because here we don’t always have perfectly async code bases and libraries.

What I’m saying is – I want to call Task.Result and not feel dirty or fearful.

Do you think future versions of .NET should offer language features like Ballerina?

For anyone who hasn’t heard of Ballerina, go visit ballerina.io. I worry about baking Ballerina type features into the language because I’m afraid we’ll end up with something like async and await where the solution covers 80% of the easy scenarios, but the last 20% is painful or near impossible.

Ballerina sample

Like it or not, C# is a general purpose programming language, so you are going to have scenarios that require boilerplate code. I do think we can make some changes to the language that can help eliminate boilerplate code. Every time I look at a project that generates Swagger docs or OpenAPI docs, there are these [Produces] attributes all over the code. The attributes are noisy and I always wonder why the tools can't figure out the real return type.

Or, better yet, why can’t the language express what I’m going to return? C# is an object oriented language so I need to write methods with a return type like IActionResult to cover all possible return types. But, IActionResult loses all the fidelity you can have with the concrete types the method actually uses. What if C# had the F# concept of a sum type, or discriminated union? Then I don’t have to lose type fidelity by specifying a return type with some base class or interface. I think changes like this would make C# and then .NET appeal to an even broader audience.

I also think .NET and the tools can continue to improve for the new world of microservices. Look at what’s happened with HttpClient over the years. The original version was impossible to use correctly, because you had to choose between network socket starvation on one hand, and infinite DNS cache lookups on the other. So, we need smarter bits of infrastructure, and we need better scaffolding tools. The scaffolding tools with MVC 5 are light years ahead of the tools in ASP.NET Core in terms of features and performance.

Thanks for reading, and thanks to every who came to see the panel live!

View from Holmenkollbakken

MVC 5 In Retrospect

Thursday, June 13, 2019 by K. Scott Allen

I've been in the guts of an ASP.NET MVC 5 application lately and have some more perspective on the improvements we take for granted in ASP.NET Core.

Oslo in Oil

  • Tag helpers are far easier to read and write compared to HTML helpers. There were days when I wanted to give up on Razor views, but tag helpers make the Razor engine second to only JSX in terms of smoothness. Of all the different techniques I've used to dynamically generate HTML, JSX and TSX are by far my favorites, and I think that’s because JSX took the approach of embedding the declarative language inside the imperative language (HTML inside of JavaScript). Embedding in the other direction, as Razor and others have done (language X inside of HTML), always seems to create scenarios with awkward syntax.

  • It is refreshing to work with a framework that embraces dependency injection, like ASP.NET Core. ASP.NET MVC danced around DI and provides a hook for a central dependency resolver, but you always have to wonder if something might not work because you’ve strayed outside the lines.

  • The artificial separation between ASP.NET MVC and the ASP.NET Web API was unfortunate and unpleasant, but follows Conway’s law.

  • The startup logic for an ASP.NET MVC application is difficult to follow. There is code in global.asax and three or four other files in the App_Start folder. I haven’t been a big fan of how ASP.NET Core applications organize startup logic (see opinion 7 and 10), but even the worst examples are far better than the MVC approach.

  • Applications built before attribute routing was popular have the worst API routes.

  • Front end builds were easy and fast when all you had to do was bundle and minify jQuery and a few other files.

  • The scaffolding tools in MVC 5 are far ahead of the scaffolding tools for ASP.NET Core. Not only are the older tools considerably faster, but they tend not to throw exceptions as often as the ASP.NET Core tooling. Hopefully, ASP.NET Core will catch up.

Latest Course on Azure and VS2019

Monday, June 10, 2019 by K. Scott Allen

My latest Pluralsight course, released last week, is Migrating Applications and Services to Azure with Visual Studio 2019. The course is similar to my getting started course for .NET developers on Azure, but leverages more tools in Visual Studio. Migrating Applications and Services to Azure with Visual Studio 2019

Enjoy!