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 find them at https://docs.microsoft.com/dotnet/core/tools/dotnet-install-script. Once you have the SDK installed, you just need to call dotnet the same way you do in Windows.
However, you must be aware of some features that are not fully compatible with Linux and macOS systems. For instance, no equivalent to the Windows Registry exists in these OSes and you must develop an alternative yourself. If needed, an encrypted JSON config file can be a good option.
Another important point is that Linux is case-sensitive, while Windows is not. Please, remember this when you work with files. Another important thing is that the Linux path separator is different from the Windows separator. You can use the Path.PathSeparator
field and all the other Path
class members to ensure your code is multi-platform.
Besides, you can also adapt your code to the underlying OS by using the runtime checks provided by .NET Core, as follows:
using System;
using System.Runtime.InteropServices;
namespace CheckOS
{
class Program
{
static void Main()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Console.WriteLine("Here you have Windows World!");
else if(RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
Console.WriteLine("Here you have Linux World!");
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
Console.WriteLine("Here you have macOS World!");
}
}
}
Creating a service in Linux
The following script can be used to encapsulate a command-line .NET Core app in Linux. The idea is that this service works like a Windows service. This can be useful, considering that most Linux installations are command-line only and run without a user logged in:
- The first step is to create a file that will run the command-line app. The name of the app is
app.dll
and it is installed inappfolder
. The application will be checked every 5,000 milliseconds. This service was created on a CentOS 7 system. Using a Linux terminal, you can type this:cat >sample.service<<EOF [Unit] Description=Your Linux Service After=network.target [Service] ExecStart=/usr/bin/dotnet $(pwd)/appfolder/app.dll 5000 Restart=on-failure [Install] WantedBy=multi-user.target EOF
- Once the file has been created, you must copy the service file to a system location. After that, you must reload
system
and enable the service so that it will restart on reboots:sudo cp sample.service /lib/systemd/system sudosystemctl daemon-reload sudosystemctl enable sample
- Done! Now, you can start, stop, and check the service using the following commands. The whole input that you need to provide in your command-line app is as follows:
# Start the service sudosystemctl start sample # View service status sudosystemctl status sample # Stop the service sudosystemctl stop sample
Now that we have learned about a few concepts, let us learn how to implement them in our use case.