Non-Functional Requirements
Once you have gathered the system requirements, it is time to think about the impact they have on the architectural design. Scalability, availability, resiliency, performance, multithreading, interoperability, security, and other subjects need to be analyzed so that we can meet user needs. We refer to these aspects as non-functional requirements.
The following topics will be covered in this chapter:
- How do .NET 5 and Azure enable scalability, availability, and resiliency?
- Performance issues that need to be considered when programming in C#
- Software usability, that is, how to design effective user interfaces
- .NET 5 and interoperability
- Achieving security by design
- Book use case – understanding the main types of .NET Core projects
Technical requirements
The samples provided in this chapter will require Visual Studio 2019 Community Edition with .NET 5 SDK installed.
You can find the sample code for this chapter at https://github.com/PacktPublishing/Software-Architecture-with-C-9-and-.NET-5.
Enabling scalability, availability, and resiliency with Azure and .NET 5
A short search on scalability returns a definition such as the ability of a system to keep working well when there is an increase in demand. Once developers read this, many of them incorrectly conclude that scalability only means adding more hardware to keep things working without stopping the app.
Scalability relies on technologies involving hardware solutions. However, as a software architect, you must be aware that good software will keep scalability in a sustainable model, which means that a well-architected software can save a lot of money. Hence, it is not just a matter of hardware but also a matter of overall software design. The point here is that the running cost of a system should also be a factor in the architectural decisions.
In Chapter 1, Understanding the Importance of Software Architecture, while discussing software performance, we proposed some good tips to overcome bad performance issues...
Performance issues that need to be considered when programming in C#
Nowadays, C# is one of the most commonly used programming languages all over the world, so good tips about C# programming are fundamental for the design of good architectures that satisfy the most common non-functional requirements.
The following sections mention a few simple but effective tips – the associated code samples are available in the GitHub repository of this book.
String concatenation
This is a classic one! A naive concatenation of strings with the +
string operator may cause serious performance issues since each time two strings are concatenated, their contents are copied into a new string.
So, if we concatenate, for instance, 10 strings that have an average length of 100, the first operation has a cost of 200, the second one has a cost of 200+100=300, the third one has a cost of 300+100=400, and so on. It is not difficult to convince yourself that the overall cost grows like m...
Usability – why inserting data takes too much time
Scalability, performance tips, and multithreading are the main tools we can use to tune machine performance. However, the effectiveness of the system you design depends on the overall performance of the whole processing pipeline, which includes both humans and machines.
As a software architect, you cannot improve the performance of humans, but you can improve the performance of man-machine interaction by designing an effective user interface (UI), that is, a user interface that ensures fast interaction with humans, which, in turn, means the following:
- The UI must be easy to learn in order to reduce the time that is needed for learning and time wasting before the target users learn to operate it quickly. This constraint is fundamental if UI changes are frequent, and for public websites that need to attract the greatest possible number of users.
- The UI must not cause any kind of slowdown in data insertion...
The fantastic world of interoperability with .NET Core
.NET Core brought Windows developers the ability to deliver their software into various platforms. And you, as a software architect, need to pay attention to this. Linux and macOS are no longer a problem for a C# lover – it is much better than that – they are great opportunities to deliver to new customers. Therefore, we need to ensure performance and multi-platform support, two common non-functional requirements in several systems.
Both console applications and web apps designed with .NET Core in Windows are almost completely compatible with Linux and macOS, too. This means you do not have to build the app again to run it on these platforms. Also, very platform-specific behaviors now have multi-platform support, as shown, for instance, by the System.IO.Ports.SerialPort
class, which, starting from .NET Core 3.0, is on Linux.
Microsoft offers scripts to help you install .NET Core on Linux and macOS. You can...
Achieving security by design
As we have seen up to here in the book, the opportunities and techniques we have for developing software are incredible. If you add all the information you will read about in relation to cloud computing in the next chapters, you will see that the opportunities just increase, as does the complexity to maintain all of this computing environment.
As a software architect, you must understand that these opportunities come with many responsibilities. The world has changed a lot in the last years. The second decade of the 21st century has required lots of technology. Apps, social media, Industry 4.0, Big Data, and artificial intelligence are no longer future objectives, but mainly current projects that you will lead and deal with in your routine.
Considering this scenario, security must have a different approach. The world has moved to regulate companies that manage personal data. For instance, GDPR – the General Data Protection Regulation –...
Book use case – understanding the main types of .NET Core projects
The development of this book's use case will be based on various kinds of .NET Core Visual Studio projects. This section describes all of them. Let us select New project in the Visual Studio File menu.
You can filter .NET Core project types by typing in the search engine, as follows:

Figure 2.19: Searching types of .NET Core projects in Visual Studio
There, you will find common C# projects (console, a class library, Windows Form, WPF), and various types of test projects, each based on a different test framework: xUnit, NUnit, and MSTest. Choosing among the various testing frameworks is just a matter of preference since all of them offer comparable features. Adding tests to each piece of software that composes a solution is a common practice and allows software to be modified frequently without jeopardizing its reliability.
You may also want to define your class library projects under...
Summary
Functional requirements that describe system behavior must be completed with non-functional requirements that constrain system performance, scalability, availability, resilience, interoperability, usability, and security.
Performance requirements come from response time and system load requirements. As a software architect, you should ensure you have the required performance at the minimum cost, building efficient algorithms and taking full advantage of the available hardware resources with multithreading.
Scalability is the ability of a system to be adapted to an increasing load. Systems can be scaled vertically by providing more powerful hardware, or horizontally by replicating and load balancing the same hardware, which increases the availability. The cloud, in general, and Azure can help us implement strategies dynamically, with no need to stop your application.
Tools such as .NET Core that run on several platforms can ensure interoperability, that is, the...
Questions
- Which are the two conceptual ways to scale a system?
- Can you deploy your web app automatically from Visual Studio to Azure?
- What is multithreading useful for?
- What are the main advantages of the asynchronous pattern over other multithreading techniques?
- Why is the order of input fields so important?
- Why is the .NET Core
Path
class so important for interoperability? - What is the advantage of a .NET standard class library over a .NET Core class library?
- List the various types of .NET Core Visual Studio projects.
Further reading
The following are some books and links you may consider reading in order to gather more information in relation to this chapter:
- https://www.packtpub.com/virtualization-and-cloud/hands-azure-developers
- https://docs.microsoft.com/en-us/azure/architecture/best-practices/auto-scaling
- https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/azure-apps/
- https://docs.microsoft.com/en-us/dotnet/standard/parallel-processing-and-concurrency
- https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/
- https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-5/
- https://docs.microsoft.com/en-us/dotnet/standard/security/
- https://docs.microsoft.com/en-us/aspnet/core/security/
- https://owasp.org/
- https://cheatsheetseries.owasp.org/cheatsheets/DotNet_Security_Cheat_Sheet.html
- https://docs.microsoft.com/en-us/aspnet/core/security/gdpr
- https://docs.microsoft.com/en-us/azure/architecture...