AAA! It's time to rewrite to .NET Coreǃ

    We all want to move to .NET Core for a long time, but something constantly interferes. For example, nothing can be done when there are not enough important APIs. Version 2.0 simplified the process with .NET Standard 2.0 , but that's not all. Well, Microsoft-gods listened to our prayers and brought in 20,000 APIs , available as a single package in NuGet!



    Who needs this at all?


    In short, everyone needs it. IMHO, the very possibility of dragging your tons of legacy to .NET Core is already enough excuse for any victims.


    Skeptics need to be reminded that .NET Core is sawn specifically for scalable web applications on all reasonable operating systems (GNU / Linux, macOS and Windows), and a special document will help to choose between Core and Framework more precisely .


    How to use it?


    First, you need to understand that the Legacy deposits themselves will not be raked. There’s nothing even to think about grabbing a million classes and dragging them with one button.


    Suppose you have run an application on ASP.NET MVC for a Windows localhost and you haven’t been fired for this. It’s time to drag it to true-on Linux running on Azure! It is better to eat an elephant piece by piece, namely:


    • Drag and drop everything onto ASP.NET Core (but continue to hold the .NET Framework as the target platform);
    • Crawl to .NET Core (but continue to use Windows);
    • Jump to GNU / Linux;
    • Launch on Azure.

    It is clear that this great plan should be approached not as the building of communism, but reasonably. For example, if you need to show big bosses the launch on Azure - this is the place to start. If you think laziness (for example, laziness, for example), our leaders wrote a special training manual on gaining faith in .NET Core .


    In short, you need to uncover NuGet, install the Microsoft.Windows.Compatibility package and find out that a huge bunch of different necessary and unnecessary APIs have become available.


    It is important to understand that this very Microsoft.Windows.Compatibility is still being violently dubbed, so all the drop dead stories are just ahead of us.


    Now there is the following set of nishtyaks (the table turned out to be huge; dude reading this post from a mobile: please forgive me!):


    ComponentStatusWindows-only
    Microsoft.Win32.RegistryAvailableYes
    Microsoft.Win32.Registry.AccessControlAvailableYes
    System.CodeDomAvailable
    System.ComponentModel.CompositionComing
    System.Configuration.ConfigurationManagerAvailable
    System.Data.DatasetExtensionsComing
    System.Data.OdbcComing
    System.Data.SqlClientAvailable
    System.Diagnostics.EventLogComingYes
    System.Diagnostics.PerformanceCounterComingYes
    System.DirectoryServicesComingYes
    System.DirectoryServices.AccountManagementComingYes
    System.DirectoryServices.ProtocolsComing
    System.DrawingComing
    System.Drawing.CommonAvailable
    System.IO.FileSystem.AccessControlAvailableYes
    System.IO.PackagingAvailable
    System.IO.Pipes.AccessControlAvailableYes
    System.IO.PortsAvailableYes
    System.managementComingYes
    System.Runtime.CachingComing
    System.Security.AccessControlAvailableYes
    System.Security.Cryptography.CngAvailableYes
    System.Security.Cryptography.PkcsAvailableYes
    System.Security.Cryptography.ProtectedDataAvailableYes
    System.Security.Cryptography.XmlAvailableYes
    System.Security.PermissionsAvailable
    System.Security.Principal.WindowsAvailableYes
    System.ServiceModel.DuplexAvailable
    System.ServiceModel.HttpAvailable
    System.ServiceModel.NetTcpAvailable
    System.ServiceModel.PrimitivesAvailable
    System.ServiceModel.SecurityAvailable
    System.ServiceModel.SyndicationComing
    System.ServiceProcess.ServiceBaseComingYes
    System.ServiceProcess.ServiceControllerAvailableYes
    System.Text.Encoding.CodePagesAvailableYes
    System.Threading.AccessControlAvailableYes

    What to do with the Windows-only API?


    Suffer, cho.

    For tankers. Not all APIs are equally portable. If you stay on Windows, there are no problems. If you want to join the holiness of Richard Stallman and Tim Cook on GNU / Linux and macOS, respectively, you will have to suffer.


    Looking at the nishtyakov tablet, we see: Windows-only components are almost half there. Good Microsoft gods, however, allow you to successfully compile such code under any platform. When we try to use a feature that does not exist, we stumble upon PlatformNotSupportedExceptionin runtime, so all of these features will need to be thickly coated with calls RuntimeInformation.IsOSPlatform():


    private static string GetLoggingPath()
    {
        // Verify the code is running on Windows.
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Fabrikam\AssetManagement"))
            {
                if (key?.GetValue("LoggingDirectoryPath") is string configuredPath)
                    return configuredPath;
            }
        }
        // This is either not running on Windows or no logging path was configured,
        // so just use the path for non-roaming user-specific data files.
        var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
        return Path.Combine(appDataPath, "Fabrikam", "AssetManagement", "Logging");
    }

    How to understand which API-scale will work only in Windows? Nobody reads the documentation, right?


    My dear copy-paste programming enthusiast with StackOverflow! Microsoft - the gods are harsh, but fair, so just a couple of weeks ago they sawed down the API Analyzer tool . With Roslyn, this tool marks the Windows-only API, and only when the target is set to .NET Core or .NET Standard.



    What to do with mistakes? As stated earlier, suffer.


    • Delete nonportable code. Why do I need a feature if it does not start on macOS? :-)
    • Work hard to refactor your code with other, more cross-platform APIs. The benefit of this update has brought such a lot.
    • Place checks on the type of OSes in those places where GNU / Linux-specific things happen that are simply not needed on Windows.

    In the example from the picture, someone is trying to subtract the settings in the Registry. You can wrap this line in a check, run it only on Windows. On GNU / Linux, the equivalent of this line will be different, much more painful.


    Note that the Windows Compatibility Pack is a meta package. Microsoft was well aware that ordinary people would not be tormented by looking for individual small packets and would like to switch to the new platform with one jump (subject to the reservations above). Nevertheless, if you are a thoughtful cool developer, then you can drag features one by one. Thus, it will be possible to throw much more dependencies on unnecessary trash.


    What's next?


    Morally preparing for porting. Install the Windows Compatibility Pack . You study nishtyaki, of which there are more than 20 thousand, including EventLog, WMI, Performance Counters, Windows Services, etc.


    If you want to make the app cross-platform, you launch the API Analyzer. You can cry a little or pull vodka.


    Unfortunately, now .NET Core does not cover the needs of desktop development. Perhaps someday this will change. But this is a completely different story.


    If you want to know more about .NET in general and .NET Core in particular, we are waiting for you at the DotNext 2018 Piter , which will be held, suddenly, in St. Petersburg. I strongly advise you to try to glue or port something to this conference to Core so that a pool of questions for speakers will accumulate.


    Also popular now: