Viktor Rosvall
Computer Engineering BA (C), Final Project Main field of study: Computer Engineering Credits: 15 hp
Semester, year: Spring, 2020
Supervisor: Martin Kjellqvist, martin.kjellqvist@miun.se Examiner: Dr. Ulf Jennehag, ulf.jennehag@miun.se Degree programme: Datateknik, 180 credits
Abstract
The objective of this study has been to examine the portability of Moni- tor ERP System AB’s existing .NET Framework codebase to .NET Core.
The study has been conducted by examining the portability of Monitor’s projects by using Microsoft’s .NET Portability Analyzer and visualizing the dependencies of projects by using AsmSpy to gain an understanding of what order projects need to be ported. An examination of used third-party libraries has also been conducted to see which libraries are not compatible with .NET Core. And an attempt to port Monitor’s root solution has been made as a proof-of-concept and to make test and build duration compar- isons between the ported solution and the old solution. The .NET Porta- bility Analyzer reported that 19 projects aren’t 100% compatible with .NET Core (+ Windows Compatibility Pack) where some projects have one miss- ing API call while others have many more. The third-party library examina- tion showed that two libraries are not compatible with .NET Core, the first is Dynamsoft Dynamic .NET TWAIN SDK which can probably be replaced with VintaSoft Twain .NET SDK, and SAP SQL Anywhere which doesn’t have a direct replacement. The results of the comparison show that test duration speeds improved on average by 22.5% with a peak of 67.6%, and build duration differences were negligible. Porting to .NET Core will not be easy, but if fixes for the 19 incompatible Monitor projects are completed and a replacement for SQL Anywhere can be found, then Monitor ERP System AB can make a successful port to .NET Core.
Keywords:.NET Core, .NET Framework, Large codebase, Migration, Mon- itor ERP System AB, Port
Acknowledgements
I would like to thank Monitor ERP System AB for providing me with a workplace at their office and also a place to stay while working in Hudiksvall.
I’m very grateful for the support of Peter Svensson and his team at Monitor has given me during my thesis project at their office.
I would also like to thank my supervisor Martin Kjellqvist from the univer- sity who gave me great guidance and was always available when I needed his help.
Acknowledgements ii
Terminology v
1 Introduction 1
1.1 Background and problem motivation . . . 1
1.2 Overall aim . . . 1
1.3 Scope . . . 1
1.4 Concrete and verifiable goals . . . 2
1.5 Outline . . . 2
2 Theory 3 2.1 Microsoft .NET Framework . . . 3
2.2 Microsoft .NET Core . . . 3
2.2.1 .NET implementation support . . . 3
2.3 NuGet . . . 4
2.4 Windows Compatibility Pack . . . 4
2.5 SAP SQL Anywhere . . . 4
2.6 MSTest . . . 5
2.7 Monitor ERP System AB’s Domain-Specific Language . . . 5
2.8 .NET Portability Analyzer . . . 5
2.9 AsmSpy . . . 5
3 Methodology 6 3.1 Workflow . . . 6
3.1.1 Pilot study . . . 6
3.1.2 Planning . . . 6
3.1.3 Construction . . . 6
3.2 Hardware and software . . . 6
4 Process 8 4.1 Portability analysis . . . 8
4.2 Project dependency analysis . . . 8
4.3 Porting . . . 9
4.4 Testing . . . 10
4.5 Building . . . 10
5 Results 11 5.1 Portability analysis . . . 11
5.1.1 First-party source code portability . . . 11
5.1.2 Third-party library compatibility . . . 12
5.2 Project dependency analysis . . . 13
5.3 Porting . . . 13
5.4 Testing . . . 14
5.5 Building . . . 16
6 Conclusion 18 6.1 Goals . . . 18
6.2 Porting . . . 18
6.3 Testing . . . 19
6.4 Building . . . 19
6.5 Recommendations . . . 19
6.6 Ethical aspects . . . 20
6.7 Method discussion . . . 20
6.8 Further studies . . . 20
References 22
A Monitor.Service.Contracts class diagram dependency graph 1
Terminology
AOT Ahead-of-time
API Application Programming Interface CAS Code Access Security
CLR Common Language Runtime DBMS Database Management System DGML Directed Graph Markup Language DSL Domain Specific Language
EIM Electronic Invoice Management GUI Graphical User Interface
JIT Just-in-time
LTS Long-term Support Monitor Monitor ERP System AB SDK Software Development Kit SSVM Server-Side View Models Std Standard Deviation
WPF Windows Presentation Foundation
1 Introduction
Porting a large codebase from one development platform to another can be a big undertaking. This report will try to provide guidance when port- ing from the Microsoft .NET Framework to the Microsoft .NET Core devel- opment platform, and it will mention solutions to problems when porting large projects to .NET Core.
This report will also present the benefits of porting to .NET Core, such as improvements in test duration speeds when running automated unit-tests, and language features only available in the newer .NET Core 3 platform.
1.1 Background and problem motivation
Monitor ERP System AB (Monitor) is currently developing an Enterprise Resource Planning (ERP) system called MONITOR G5 for small- to medium- sized manufacturing companies. MONITOR G5 features six modules that cover all activities of manufacturing companies [1].
Monitor is currently using the classic .NET Framework that is tightly cou- pled to Windows for development of MONITOR G5. The new .NET Core platform offers cross-platform development which would allow Monitor application servers and other Monitor products to run on Mac OS and Linux.
Monitor wants to future-proof their codebase by upgrading to .NET Core as newer versions of the C# language won’t be supported on .NET Framework.
Monitor would also like to support cross-platform development to reduce the cost of running Windows virtual machines in the cloud.
1.2 Overall aim
The projects aim is to provide Monitor with a report on how to migrate their codebase to the new .NET Core Platform. This report will include the chal- lenges of such a migration and possible solutions. It will also include mea- surements comparing build times and automated unit-test duration after a migration, to see if automated tests and the building process can increase in speed after a migration to .NET Core is completed.
1.3 Scope
This study will mostly focus on the theoretical aspects of porting Monitor’s current .NET Framework Application Server to the new .NET Core plat-
Because of the sheer size of Monitor’s codebase, this work will only cover the process of porting the Monitor.Service.Contracts solution and its projects which has no or few dependencies on other Monitor solutions and projects as a proof-of-concept while documenting the process.
1.4 Concrete and verifiable goals
The goals of this report are to answer the following questions:
1. Examine the codebase for portability issues 2. Locate incompatible third-party libraries 3. Examine tools used to aid in porting
4. Successfully port the root solution of projects 5. Document the porting process
6. Measure the change in test time duration 7. Measure the change in build time duration
1.5 Outline
Chapter 2 describes some of the technologies used to help the reader un- derstand the result better. Chapter 4 describes the work process of porting and usage of tools to gather data. Chapter 5 contains the results of the work process. Chapter 6 describes the conclusions derived from the results and recommendations to Monitor ERP System AB for how to proceed.
2 Theory
This chapter shortly describes the products and technologies used by Mon- itor ERP System AB for their MONITOR Server application.
2.1 Microsoft .NET Framework
Microsoft’s .NET Framework is a proprietary platform that supports build- ing and running Windows applications and websites [2]. A large com- ponent of the .NET Framework is called the Common Language Runtime (CLR), and similarly to the Java Virtual Machine, handles memory man- agement, thread execution, garbage collection and code execution [2], [3].
Another large component of the .NET Framework is the class library it pro- vides that includes functions for creating graphical user interfaces, file man- agement and collections of data structures [3].
2.2 Microsoft .NET Core
Microsoft’s .NET Core is an open-source platform that, similarly to .NET Framework, supports building and running Windows applications and web- sites. The .NET Core libraries component also allows for cross-platform de- velopment over Windows, Unix, Linux and OSX. .NET Core provides both platform-agnostic features as well as platform-specific features. The .NET Core Runtime provides assembly loading, type system and a garbage col- lector. [4]
Microsoft .NET Core compared to the earlier .NET Framework version has a few differences. Firstly, .NET Core doesn’t support certain App-models such as ASP.NET Web Forms and ASP.NET MVC, however, .NET Core does support WPF and Windows Forms on Windows. Secondly, the Subsystem Code Access Security (CAS) isn’t supported on .NET Core anymore. [4]
Microsoft .Net Core 3.1 was released December 3, 2019 and has Long Term Support (LTS) for three years until December 3, 2022. [5]
2.2.1 .NET implementation support
Table 1 lists the minimum platform version that supports .NET Standard. For example, a library targeting .NET Standard 1.3 can be used by .NET Core 1.0 and .NET Core 3.0. [6]
.NET Standard 1.3 1.4 1.5 1.6 2.0 2.1 .NET Framework 4.6 4.6.1 4.6.1 4.6.1 4.6.1 N/A
.NET Core 1.0 1.0 1.0 1.0 2.0 3.0
Table 1: .NET implementation support [6]
2.3 NuGet
NuGet is the package manager for .NET projects. It can create, share and import packaged libraries into .NET projects. NuGet packages are ZIP files with a .nupkg suffix containing compiled assemblies (DLL files). NuGet packages can be hosted both publicly and privately, making them useful for teams working together to easily share libraries. [7]
Figure 1: NuGet workflow [7]
2.4 Windows Compatibility Pack
The Windows Compatibility Pack is an extension of .NET Standard ob- tained using NuGet. The pack includes Windows-only features that are present in .NET Framework but isn’t included in the cross-platform .NET Core or .NET Standard. The Windows Compatibility Pack is intended to ease the transition between .NET Framework and .NET Core by provid- ing a similar API for Windows-only technologies. It’s a useful first step for developers that want to move to .NET Core but is only going to support Windows for a start. [8], [9]
2.5 SAP SQL Anywhere
SQL Anywhere is a proprietary light-weight relational database manage- ment system (RDBMS) that is often deployed in embedded applications, and it provides enterprise-calibre functionality [10]. SQL Anywhere fea- tures data synchronization technologies that enable shared data modified by
applications to be propagated to other databases, and vice versa, it allows changes made at the central server to be propagated to remote databases [11].
SAP SQL Anywhere doesn’t support .NET Core and isn’t planning on doing so at this time. [12], [13]
2.6 MSTest
MSTest is a cross-platform framework for building unit-tests targeting both .NET Framework and .NET Core. [14] This means that tests written for .NET Framework will also work for .NET Core.
2.7 Monitor ERP System AB’s Domain-Specific Language
Monitor ERP System AB has developed a Domain-Specific Language (DSL) for generating code called recipes that declares views and contracted Server- Side View Models (SSVM).
2.8 .NET Portability Analyzer
The .NET Portability Analyzer is a tool available both as a console app and as a Visual Studio Extension. The extension can only analyze one assembly at a time, while the console app can analyze directories recursively. The tool will analyze assemblies and make a detailed Excel file containing a proba- bility of successfully porting the codebase to the targeted platform. It will also create a page detailing all the missing .NET APIs on the targeted .NET Platform and give a recommended action to fix the problem if a known so- lution exists. [15]
2.9 AsmSpy
AsmSpy is a command-line for viewing references between assemblies. It can search recursively and filter out both system assemblies while searching for files matching specified patterns. For smaller projects, AsmSpy can out- put the references as a tree in the console. AsmSpy can also save the refer- ence tree formatted as either a Directed Graph Markup Language (DGML), Graph Description Language (DOT) or an Extensible Markup Language (XML) file. [16]
3 Methodology
This chapter contains the workflow of this project. It includes a description of the pilot study, planning and construction. It also includes how the third- party libraries and Monitor ERP System AB’s developed technologies were studied.
3.1 Workflow
The project workflow will be subdivided into three sequential phases: pilot study, planning and construction.
3.1.1 Pilot study
The pilot study is conducted for gaining an understanding of the .NET ecosystem, and researching what tools and documentation are available for developers. The pilot study also included a brief look at what self- developed technologies and third-party libraries Monitor is currently using.
3.1.2 Planning
The planning phase includes analyzing Monitor’s source code is for porta- bility issues and dependency mapping. The result of this analysis can later be used when planning what order Monitor’s projects should be ported and to gain an understanding of the amount of work required to undertake the porting process.
It’s important to note that the analyzing tools were used recursively inside Monitor’s BuildOutput directory. This is because the tools work best when their input is the compiled assembly files instead of .NET project files.
3.1.3 Construction
The construction phase is where the porting process takes place. Monitor projects from the Monitor.Service.Contracts solution is ported to .NET Core while documenting the process. The ported .NET Core projects can then be compared to the .NET Framework projects when it comes to test and build time duration differences.
3.2 Hardware and software
Hardware and software used when running automated test-code and com- piling:
• Intel Core i7-9850H 2.60Hz
• Microsoft .NET Core 3.1.2
• Microsoft .NET Framework 4.6
• Windows 10.0.17134
• Visual Studio 2019
4 Process
This chapter describes the process of porting the Monitor.Service.Contracts solution to .NET Core.
4.1 Portability analysis
To identify third-party tools that are in use by Monitor and to analyze the portability of Monitor’s first-party projects, the Microsoft .NET Portabil- ity Analyzer is run on the BuildOutput of all solutions with the command shown in listing 1
1 A p i P o r t . exe a n a l y z e - p - b - u - t " . NET Co r e + P l a t f o r m
E x t e n s i o n s " - f " ../ s o u r c e / r e p o s / Dev / B u i l d O u t p u t / " - o " port - analyze - r e s u l t s / B u i l d A l l V S 2 0 1 9 - c o r e + ext . xl s x "
Listing 1: Microsoft .NET Portability Analyzer run on all assemblies The analyzer will create a summary of all assembly files in the directory and give a scoring on the probability of a successful port to .NET Core (+
Windows Compatibility Pack). The analyzer will also create a detailed page of all API calls that are missing from .NET Core, and if available, a recom- mended action is also described.
With data from the analyzer, decisions can be made on what third-party libraries need to be replaced, and which can simply be updated. And a high-level overview of which first-party projects need to be re-written, and which can be updated to .NET Core with no modification on source code.
4.2 Project dependency analysis
The built .NET Framework assemblies can be analyzed to determine their dependencies. An open-source tool called AsmSpy can analyze the assem- blies and output a DGML file [16]. The AsmSpy software is run on the BuildOuput directory as shown in listing 2, which creates the DGML file.
1 A s m S p y . exe ../s o u r c e/ r e p o s / Dev / B u i l d O u t p u t - - n o n s y s t e m - - i n c l u d e s u b - - r e f e r e n c e d s t a r t s w i t h " M o n i t o r " - - d g m l "
d e p e n d e n c y _ g r a p h . dg m l "
Listing 2: AsmSpy [16] run on BuildOutput to generate a DGML file Visual Studio 2019 has a component called the DGML Editor for editing and viewing DGML files, and is necessary for the opening of DGML files.
There’s also a third-party package for Visual Studio 2019 called DgmlPow- erTools2019 [17], and it has features suitable for working on node graphs with a large number of nodes and edges.
With the DGML file open in Visual Studio’s DGML editor, it’s possible to hide all test-projects by searching for all projects that include ".tests" and selecting "hide selected". A layout change to "Bottom to Top" will create a tree-like structure, placing the most dependent project (with no dependen- cies) at the very top. This allows ease of access of what order the projects should be ported to .NET Core.
All projects further down the tree are dependent on some project or projects higher up in the tree. By selecting a project further down and selecting
"Outgoing Dependencies", all projects the selected project depend on will be highlighted.
4.3 Porting
Begin by porting projects to .NET Core with no dependencies on other projects, and expand to new projects that depend on previously ported projects next.
The Windows Compatibility Pack is imported from NuGet to get access to Windows-only .NET Framework API calls. Projects with no dependencies or projects whose dependencies have already been ported to .NET Core can be found using the project dependency graph described in chapter 4.2.
1. Create a new .NET Core 3.1 Class Library project with the same name as the original .NET Framework project, and add it to a new or existing .NET Core solution
2. Copy the source code from the original .NET Framework project to the new .NET Core project. Watch out for excluded files from .NET Framework projects being included in the .NET Core project as they may cause problems
3. Add references to other Monitor projects and add third-party libraries with NuGet as needed. Some third-party libraries have removed API calls in their newer versions, but it’s possible to add references to older versions of the library (including .NET Framework versions of the li- brary)
4. Disable the GenerateSerializationAssemblies property in .csproj (due to a serialization bug [18])
5. Disable the GenerateAssemblyInfo property in .csproj (allows use of pre- viously generated AssemblyInfo.cs files [19])
6. Replace code calls to APIs no longer supported in .NET Core
Use the summary and detailed description generated by the Portability An- alyzer to find and correct the source code using API calls to missing .NET
1 M e a s u r e - C o m m a n d { & " C :\ P r o g r a m F i l e s ( x86 ) \ M i c r o s o f t V i s u a l S t u d i o \ 2 0 1 9 \ P r o f e s s i o n a l \ M S B u i l d \ C u r r e n t \ Bin \ M S B u i l d . exe " .\
M o n i t o r . S e r v i c e . C o n t r a c t s . sln / p :C o n f i g u r a t i o n= D e b u g / p : P l a t f o r m =" Any CPU " / m / v : m i n i m a l }
Listing 3: Measured run for MSBuild
1 M e a s u r e - C o m m a n d { d o t n e t b u i l d " .\ M o n i t o r . S e r v i c e . C o n t r a c t s . sln
" - v m i n i m a l -- n o - r e s t o r e }
Listing 4: Measured run for dotnet build
The steps for porting MSTest projects are the same, except for the creation of new .NET Core MSTest projects instead of class libraries.
4.4 Testing
Because Monitor has written all their unit-tests using the MSTest frame- work, no test-code had to be re-written. The ported .NET Core test-projects are run in sequence ten times to get an average and standard deviation of the time duration it takes to complete all tests. Then the same steps for test- ing are applied for the original .NET Framework test-projects. The result of the test duration measurements is presented in section 5.4.
4.5 Building
Monitor’s existing build process use MSBuild [20] to build their .NET Frame- work solutions, while .NET Core is built with dotnet build [21]. To make sure there is a fair comparison between Monitor’s existing build process and a new .NET Core-based build process the builds were run with similar argu- ments to each other. The projects are built to an empty output directory ten times to get an average build time.
For measuring the time it takes to run the build scripts, a PowerShell utility command called Measure-Command [22] is run with the build script as an argument as shown in listing 3 and 4.
5 Results
This chapter details the result of porting the Monitor.Service.Contracts so- lution projects to .NET Core and the performance changes it resulted in.
5.1 Portability analysis
This section focuses on the portability of both third-party libraries and Mon- itor’s first-party source code, and it contains a table detailing the Monitor projects that aren’t 100% .NET Core compatible.
5.1.1 First-party source code portability
This section focuses on Monitor’s first-party source code and it’s portability to .NET Core. By using the method described in chapter 4.1, a spreadsheet of projects with a portability probability is constructed.
Table 2 show an overview of the total number of Monitor projects that needs to be ported. The table shows that 19 projects are not compatible with .NET Core and would need to be fixed. The table also shows that 133 projects and all 90 test-projects are reported portable according to the .NET Portability Analyzer.
Type Count
Incompatible-project 19 Compatible-project 133 Incompatible-test-project 0
Compatible-test-project 90
Total 242
Table 2: Overview of Monitor projects (as given by the analyzer)
See table 3 for a view of projects that need their source code modified before being .NET Core compatible. A lower probability means that more source code needs to be modified, meaning a project with a 99% probability might have one missing API call, while a probability of 75% is going to have more missing API calls.
Project Probability Monitor.Installer.ServerServiceHost 75.81
Monitor.Updater.ServiceHost 76.74 Monitor.Web.ServiceHost 79.00 Monitor.Server.Service 82.02 Monitor.Installer.Logic.Framework 93.59
Monitor.Updater 95.68
Monitor.Installer.WiX.Common 97.20 Monitor.Core.DefaultImplementations 98.10 Monitor.RecipeCompiler 98.49
Monitor.Installer 98.91
Monitor.Server 98.92
Monitor.InstallationManager 99.06 Monitor.ComponentModel 99.09 Monitor.Installer.WiX 99.21 Monitor.Client.Shared 99.52 Monitor.StrawberryFields.Backend 99.57 Monitor.StrawberryFields.Shared 99.89
Monitor.Core 99.94
Monitor.Client 99.97
Table 3: Probability (as given by the analyzer) of Monitor projects portability
During the process of porting the Monitor.StrawberryFields.Backend project, which has a reported probability of a successful port at 99.57% (which equals three missing API calls), it was found that no replacement for the .NET Framework API call in used was available. The problem stems from a lack of a LamdaExpression.CompileToMethod API call in .NET Core, as it seems to have been removed and forgotten [23]–[25]. A potential replacement is to use the Cecil library to generate code in the future [26]. A port to .NET Core is blocked until this issue has been resolved.
5.1.2 Third-party library compatibility
This section focuses on the compatibility of third-party libraries. The prob- lematic third-party library .NET Core compatibility is presented in table 4.
Library .NET Core support
CsQuery x
Dynamic .Net TWAIN x
ScintillaNET 3.1 (fork)
SAP SQL Anywhere x
Table 4: Third-party library .NET Core compatibility. [12], [27]–[29]
Potential replacements for the third-party libraries shown in table 4:
• CsQuery is included in the BuildOutput directory and therefore in- cluded in the API Portability Analyzer report. The Monitor.Server.Tests project is referencing CsQuery, but no source code is using CsQuery so it can be safely deleted.
• Dynamsoft Dynamic .Net TWAIN provides an API for TWAIN devices such as scanners [28]. Monitor is currently using their solution to scan invoices for Monitor’s Electronic Invoice Management (EIM) system [30]. Dynamic .Net TWAIN is currently only used in one class that is responsible for scanning invoices, therefore it might be possible to replace Dynamic .Net TWAIN for another third-party library that sup- ports .NET Core.
A potential replacement for Dynamsoft Dynamic .Net TWAIN is the VintaSoft Twain .NET SDK which provides similar features as the cur- rent library while also supporting .NET Core [31].
• ScintillaNET has no official support for .NET Core [32], but there’s a community fork with .NET Core support available [29], [32], [33].
• SAP SQL Anywhere had its latest released in 2015 [34], and has had no further releases since, and they have no interest to support .NET Core [12].
A potential replacement for SAP SQL Anywhere is Microsoft SQL Server as they provide support for .NET projects and it’s possible to host the server both locally and on Azure. [35]
5.2 Project dependency analysis
Appendix A show a zoomed out view of Monitor’s project dependency graph, where all purple projects are those that the .NET Portability Ana- lyzer in section 4.1 marked as not 100% compatible with .NET Core. These purple projects will, therefore, require changes to the source code to com- plete the porting process.
As seen in appendix A, all Monitor’s projects are connected by references, thus all projects will need to be ported to .NET Core. This presents a prob- lem because if one project can’t be ported, then it may block other Monitor projects that depend on the blocked project from being ported to .NET Core.
5.3 Porting
Appendix A, Monitor.StrawberryFields.Backend is a core project that has many dependent projects (such as Monitor.ComponentModel.Tests), and it wasn’t able to be ported to .NET Core due to missing API calls to Lam- daExpression.CompileToMethod which is essential for Monitor’s DSL code- generation system. The rest of the projects in Monitor.Service.Contracts weren’t able to be ported to .NET Core because (as can be seen in Appendix A) they were depending on Monitor.StrawberryFields.Backend.
Project name Source code Test-project
Monitor.ComponentModel o x
Monitor.Serialization.Json.NewtonSoft o o
Monitor.Serialization.Tolerant o o
Monitor.StrawberryFields.Backend x x
Monitor.StrawberryFields.Frontend o o
Monitor.StrawberryFields.Shared o o
Monitor.Utils.UnitTestExtensions o o
Table 5: Result of porting Monitor projects to .NET Core
5.4 Testing
A total of five test-projects was successfully ported to .NET Core, with no need to re-write any test-project source code. The test duration for .NET Framework unit-tests is presented in table 6. The .NET Core unit-test du- ration times is presented in table 7. Figure 2 illustrate a comparison be- tween .NET Framework and .NET Core test-projects test duration, and table 3 show a comparison for the accumulated test times for all test-projects.
The results show an improvement of 22.5% in test duration reduction on .NET Core when calculating the percentage of change between the total av- erage times. And when focusing at the NewtonSoft.Tests the average test time duration is improved by 67.6% as the average time for the test is re- duced from 198.7ms to 64.4ms. The time improvements vary a lot depend- ing on the number of tests and what kind of operations is performed.
Project Count Average(ms) Std
Serialization.Json.NewtonSoft.Tests 6 198.7 5.36 Serialization.Tolerant.Tests 85 206.7 5.87 StrawberryFields.Frontend.Tests 5 14.3 0.48 StrawberryFields.Shared.Tests 463 904.1 7.29 Utils.UnitTestExtensionsTests 17 120.7 1.49
Total 576 1444.5
Table 6: Test duration for five Monitor .NET Framework test-projects
Project Count Average(ms) Std Serialization.Json.NewtonSoft.Tests 6 64.4 1.07
Serialization.Tolerant.Tests 85 194 3.89 StrawberryFields.Frontend.Tests 5 8.4 0.97 StrawberryFields.Shared.Tests 463 743.9 7.99 Utils.UnitTestExtensionsTests 17 109.5 1.08
Total 576 1120.2
Table 7: Test duration for five ported Monitor .NET Core test-projects
0 200 400 600 800 1000
Serialization.Json.NewtonSoft.Tests Serialization.Tolerant.Tests StrawberryFields.Frontend.Tests StrawberryFields.Shared.Tests Utils.UnitTestExtensionsTests
Test duration (ms) (lower is better) .NET Core .NET Framework Figure 2: Test duration comparison between tables 6 and 7
0 500 1000 1500 Total
Test duration (ms) (lower is better) .NET Core .NET Framework
Figure 3: Total time test duration comparison between tables 6 and 7
5.5 Building
This section will focus on building Monitor’s Monitor.Service.Contracts so- lution and comparing the build times between .NET Framework’s MSBuild and .NET Core’s dotnet build.
Table 8 show that the build time difference between them is only 40ms. The standard deviation is overlapping, (see figure 4) so the build time difference is negligible.
Builder Time(s) Std MSBuild 2.48 0.34 dotnet-build 2.52 0.48
Table 8: Build duration for the Monitor.Service.Contracts solution
1.5 2 2.5 3 3.5 MSBuild
dotnet-build
Test duration (ms) (lower is better) Figure 4: Build times comparison for table 8
6 Conclusion
This chapter contains a summary of the goals, my personal thoughts and recommendations based on conclusions from the results.
6.1 Goals
This section includes summaries answering the questions asked in section 1.4
1. As detailed in table 2 and table 3, we can see that Monitor has 19 projects currently not portable. Most of these project have a high scor- ing on the probability of being portable. This means that most of the projects only require a small amount of modification to be portable.
2. As detailed in table 4, we can see that four third-party libraries are not .NET Core compatible. However as explained in section 5.1.2, all but SAP SQL Anywhere can easily be replaced.
3. The tools used to aid in the porting process mentioned in this thesis are the .NET Portability Analyzer (section 2.8) and AsmSpy (section 2.9).
4. The root solution called Monitor.Service.Contracts wasn’t entirely portable due to Monitor.StrawberryFields.Backend project having missing .NET Core API calls. This meant that all projects in the solution weren’t able to be ported. Table 5 show the 6 projects and 5 test-code projects that were successfully ported to .NET Core
5. The porting process was documented in section 4.3
6. The test time duration comparison between the ported .NET Core projects and .NET Framework projects can be seen in figure 2 and fig- ure 3.
7. The build time duration comparison can be seen in figure 4
6.2 Porting
As seen in table 3, the projects with the most missing API calls are the Mon- itor.Installer and Monitor.Updater projects. And as mentioned in section 5.1.2, SQL Anywhere is not supported on .NET Core. Replacing a database driver isn’t easy because existing backend code and SQL queries need to be re-written, and loss of data during the migration between SQL Anywhere and the replacement database management system (DBMS) is unacceptable.
Microsoft claims that no more .NET Framework APIs is going to be ported to .NET Core 3, instead, they have provided different more modern replace- ments [36]. This may prompt a re-write of problematic source code to (what they consider) a modern approach.
It is possible to target older assemblies from third- or first-party libraries in what Microsoft calls .NET Framework Compatibility Mode [37]. But do- ing so prohibits the update of said assemblies. If libraries aren’t updated, then there’s a risk of exposure to security flaws present in the older version.
There’s also the hassle of maintaining a codebase that’s using two different frameworks at the same time if this approach is used.
6.3 Testing
The MSTest framework for unit-testing is fully compatible with .NET Core, meaning all Monitor’s test-projects for unit-testing can be ported over with minimal effort. In this rather small sample size of 576 unit-tests, a 22.5%
improvement can be seen when measuring the test duration of .NET Core compared to .NET Framework. However as seen in figure 2, improvements vary between a few percent to 67.7%,
6.4 Building
Building .NET Core projects is different from .NET Framework projects in that a different build tool is used which has different parameters. The .csproj file detailing the project references and what files are to be compiled has also changed to where a lot less need to be written.
6.5 Recommendations
A plan of what order the projects will be ported to .NET Core can be made according to their location in the dependency graph, how portable it is and the number of dependent projects a project has.
A first step may be to upgrade to .NET Core with the Windows Compati- bility Pack. This allows for a more seamless migration when porting .NET Framework projects that rely on Windows-only technologies to .NET Core, but it hinders cross-platform compatibility with Linux and OSX until the windows-only code has been re-written. A port to .NET Core will also en- able C# 8 language features such as async-streams, ahead-of-time (AOT) compilation, and a more high-performance scalable runtime [38].
A base-line for a time and cost estimation for porting the codebase to .NET
at the missing method calls the projects that have portability issues are using to estimate how difficult it is to re-write that code.
For Monitor ERP System AB to port their codebase to .NET Core, they will need to replace SAP SQL Anywhere and fix the portability issues of the 19 projects detailed in table 3.
If missing API support in .NET Core 3 were to block the porting process, then an option can be to start preparing the codebase for .NET 5 that is scheduled to release in November 2020. All .NET platforms will be united in .NET 5, making .NET Framework and .NET Core legacy platforms [39].
6.6 Ethical aspects
Care has been taken to make sure Monitor’s trade-secrets and source code wasn’t leaked when using the automated tools for code analysis. This thesis project will also be reviewed by Monitor ERP System AB before publication to ensure no sensitive information is leaked.
6.7 Method discussion
Since writing this thesis, Microsoft has greatly improved their documenta- tion on how they recommend projects should be ported to .NET Core [40].
The process they describe include re-targeting all projects to .NET Frame- work 4.7.2 and converting all packages.config files to the new .NET Core for- mat before attempting to begin the porting process. Readers are therefore advised to consult Microsoft’s documentation as best-practices and new tools may be developed.
6.8 Further studies
Since the sample size of unit-tests and buildable .NET Core projects is too small, further studies need to be done on much larger sample size. Testing the performance differences with more unit-tests is necessary to gain a bet- ter understanding if more tests would decrease or increase the average test duration. As can be seen in table 2, a total of 152 projects can be used in further studies after a completed porting process to test the build duration differences. And tests on incremental build speeds could also be tested as it may more accurately reflect real-world building by developers.
Further studies also need to be done for the integration-test projects be- cause they weren’t ported to .NET Core due to them being further down the project dependency graph shown in appendix A. The .NET Portability Analyzer gave them a 100% portability scoring, but it’s unclear if they are truly portable since it wasn’t tested in this report.
Client and server startup time and responsiveness on a fully ported .NET Core codebase can be tested using both ahead-of-time (AOT) compilation vs just-in-time (JIT) compilation. Tiered compilation was introduced in .NET Core 3.0 for the JIT compiler and it promises faster startup times by gener- ating less optimized code at startup, and instead re-generating more opti- mized code for frequently hit methods [41].
The performance of different database drivers compared to SAP SQL Any- where could be further studied to determine what database driver replace- ment is suitable most suitable for Monitor.
References
[1] Monitor. MONITOR ERP SYSTEM. cited 12 Jun 2020. URL: https : //monitorerp.com/erp-system/.
[2] Microsoft. What is .NET Framework? cited 25 Mar 2020.URL: https://
dotnet.microsoft.com/learn/dotnet/what-is-dotnet-framework.
[3] Microsoft. Overview of .NET Framework. cited 25 Mar 2020.URL: https:
/ / docs . microsoft . com / sv - se / dotnet / framework / get - started / overview.
[4] Microsoft. About .NET Core. cited 25 Mar 2020. URL: https://docs.
microsoft.com/sv-se/dotnet/core/about.
[5] Microsoft. .NET Core Support Policy. cited 26 Mar 2020. URL: https:
//dotnet.microsoft.com/platform/support/policy/dotnet-core.
[6] Microsoft. .NET Standard. cited 26 Mar 2020. URL: https : / / docs . microsoft.com/en-us/dotnet/standard/net-standard.
[7] Microsoft. An introduction to NuGet. cited 02 Jun 2020. URL: https : //docs.microsoft.com/en-us/nuget/what-is-nuget.
[8] Microsoft. Use the Windows Compatibility Pack to port code to .NET Core.
cited 26 Mar 2020. URL: https : / / docs . microsoft . com / en - us / dotnet/core/porting/windows-compat-pack.
[9] Gavrysh O. How to port desktop applications to .NET Core 3.0. cited 26 Mar 2020.URL: https://devblogs.microsoft.com/dotnet/how-to- port-desktop-applications-to-net-core-3-0/.
[10] SAP SQL Anywhere. Data management technologies. cited 23 Mar 2020.
URL: https://help.sap.com/viewer/5c834e66874441e7b5017d502bbc12d0/
17.0/en-US/8156081d6ce210148b7cd44e397c46f0.html.
[11] SAP SQL Anywhere. Overview of data exchange technologies. cited 23
Mar 2020.URL: https://help.sap.com/viewer/5c834e66874441e7b5017d502bbc12d0/
17.0/en-US/815685d36ce21014b4c3d2393471577d.html.
[12] Ian McHardy. Planned .NET Core support (again)? cited 26 Mar 2020.
URL: http : / / sqlanywhere - forum . sap . com / questions / 34551 / planned-net-core-support-again/34570.
[13] Microsoft. Database Providers. cited 26 Mar 2020.URL: https://docs.
microsoft. com/ en- us /ef / core/ providers/ ?tabs= dotnet- core- cli.
[14] Microsoft. Microsoft Test Framework "MSTest V2". cited 26 Mar 2020.
URL: https://github.com/Microsoft/testfx.
[15] Microsoft. The .NET Portability Analyzer. cited 26 Mar 2020.URL: https:
/ / docs . microsoft . com / en - us / dotnet / standard / analyzers / portability-analyzer.
[16] Mike Hadlow. AsmSpy. cited 16 Apr 2020.URL: https://github.com/
mikehadlow/AsmSpy.
[17] Chris Lovett. DgmlPowerTools 2019. cited 16 Apr 2020. URL: https : //marketplace.visualstudio.com/items?itemName=ChrisLovett.
DgmlPowerTools2019.
[18] Sujay Sarma. Build with "Generate serialization assembly: On" throws er- rors. cited 01 Apr 2020. URL: https : / / github . com / dotnet / core / issues/2716/.
[19] .NET Contributors. Port existing applications to .NET Core 3.1. cited 09 Apr 2020. URL: https : / / github . com / dotnet / winforms / blob / master/Documentation/porting-guidelines.md.
[20] Microsoft. MSBuild command-line reference. cited 15 Apr 2020.URL: https:
/ / docs . microsoft . com / en - us / visualstudio / msbuild / msbuild - command-line-reference?view=vs-2019.
[21] Microsoft. dotnet build. cited 15 Apr 2020.URL: https://docs.microsoft.
com/en-us/dotnet/core/tools/dotnet-build.
[22] Microsoft. Measure-Command. cited 15 Apr 2020.URL: https://docs.
microsoft.com/en-us/powershell/module/microsoft.powershell.
utility/measure-command?view=powershell-7.
[23] Jon Hanna. API Change: Restore CompileToMethod in S.L.Expressions.
cited 02 Apr 2020. URL: https : / / github . com / dotnet / runtime / issues/20270.
[24] Psilon. FEATURE_COMPILE_TO_METHODBUILDER compiler constant clarification. cited 02 Apr 2020. URL: https://github.com/dotnet/
runtime/issues/19943.
[25] Bart J.F. De Smet. Review disabled features in expression interpreter code.
cited 02 Apr 2020. URL: https : / / github . com / dotnet / runtime / issues/19107.
[26] Jb Evain. Cecil. cited 02 Apr 2020.URL: https://github.com/jbevain/
cecil.
[27] James Treworgy. CsQuery. cited 03 Apr 2020.URL: https://github.
com/jamietre/CsQuery.
[28] Dynamic. What Is Dynamic .NET TWAIN. cited 14 Apr 2020.URL: https:
/ / www . dynamsoft . com / Documents / Dynamic % 20 . NET % 20TWAIN % 20Developer’s%20Guide.pdf.
[29] Fernando Andreu. ScintillaNET NuGet fork. cited 25 May 2020. URL: https://www.nuget.org/packages/fernandreu.ScintillaNET.
[30] Monitor ERP System AB. General Information about Electronic Invoice Management. cited 14 Apr 2020.URL: http://help.monitor.se/EN/
MONITOR/9_0/Content/Tillampningar/EFH/elektronisk_fakturahantering.
htm.
[31] Vinta Software. VintaSoft Twain .NET SDK. cited 14 Apr 2020. URL: https://www.vintasoft.com/vstwain-dotnet-index.html.
[32] Martijn Sneijders. .NET Core 3.0 compatible. cited 25 May 2020. URL: https://github.com/jacobslusser/ScintillaNET/issues/469.
[33] Fernando Andreu. ScintillaNET fork. cited 03 Apr 2020. URL: https:
//github.com/fernandreu/ScintillaNET.
[34] Chris Kleisath. Announcing SQL Anywhere 17! cited 14 Apr 2020.URL: https://blogs.sap.com/2015/07/15/announcing- sql- anywhere- 17-2/.
[35] Microsoft. SQL Server. cited 14 Apr 2020.URL: https://www.microsoft.
com/en-gb/sql-server/default.aspx.
[36] Scott Hunter. .NET Core is the Future of .NET. cited 21 Apr 2020.URL: https : / / devblogs . microsoft . com / dotnet / net - core - is - the - future-of-net/.
[37] Microsoft. .NET Framework compatibility mode. cited 02 Jun 2020. URL: https://docs.microsoft.com/en-us/dotnet/core/porting/third- party-deps#net-framework-compatibility-mode.
[38] Microsoft. .NET Core overview. cited 20 Apr 2020.URL: https://docs.
microsoft.com/en-us/dotnet/core/about.
[39] Richard Lander. Introducing .NET 5. cited 20 Apr 2020. URL: https:
//devblogs.microsoft.com/dotnet/introducing-net-5/.
[40] Microsoft. Overview of porting from .NET Framework to .NET Core. cited 02 Jun 2020. URL: https : / / docs . microsoft . com / en - us / dotnet / core/porting/.
[41] Stephen Toub. Performance Improvements in .NET Core 3.0. cited 20 Apr 2020.URL: https://devblogs.microsoft.com/dotnet/performance- improvements-in-net-core-3-0/.
A Monitor.Service.Contracts class dia- gram dependency graph
Purple projects are those that the .NET Portability Analyzer in chapter 4.1 marked as not 100% compatible with .NET Core.
The class diagram shown on the next page.
Monitor.API.Backend Monitor.API.Client
Monitor.API
Monitor.API.Implementation
Monitor.API.Implementation.IntegrationTests Monitor.API.Intercom
Monitor.Backup.BackupTool Monitor.Backup.Core
Monitor.Backup.Core.resources Monitor.BusinessIntelligence
Monitor.BusinessIntelligence.IntegrationTests
Monitor.Client
Monitor.Client.NoCheck Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources Monitor.Client.resources
Monitor.Client.Shared Monitor.Client.Theme
Monitor.Core.ArrivalReporting
Monitor.Core.CustomerOrderTransfer
Monitor.Core.DefaultImplementations Monitor.Core.DefaultImplementations.MonitoringTasks
Monitor.Core
Monitor.Core.IntegrationTests Monitor.Core.MonitoringTasks
Monitor.Core.Phrases
Monitor.Core.Phrases.resources Monitor.Core.Phrases.resources Monitor.Core.Shared
Monitor.Core.Web
Monitor.CountryPackage.DE
Monitor.CountryPackage.DK Monitor.CountryPackage.FI Monitor.CountryPackage.MY Monitor.CountryPackage.PL Monitor.CountryPackage.Minimal Monitor.CountryPackage.EE Monitor.CountryPackage.SE Monitor.DatabaseConverter.Common
Monitor.DatabaseConverter.Core
Monitor.DatabaseConverter Monitor.DatabaseConverter.Import
Monitor.DatabaseConverter.Importer Monitor.DatabaseConverter.Importer.Infrastructure
Monitor.DatabaseCreator.Importer
Monitor.DatabaseMigrator Monitor.DatabaseMigrator.Importer
Monitor.DbTool Monitor.DbTool.GUI
Monitor.Dto.Edi Monitor.FormReports
Monitor.GenericSearch
Monitor.GenericSearch.IntegrationTests
Monitor.InstallationManager
Monitor.Installer.ActionHandler
Monitor.Installer.API
Monitor.Installer.API.Server
Monitor.Installer.API.ServerConsoleHost Monitor.Installer.API.ServerServiceHost
Monitor.Installer.AutomaticInstaller
Monitor.Installer.ConsoleUtility Monitor.Installer.CustomReports Monitor.Installer.CustomFormReports
Monitor.Installer
Monitor.Installer.ErrorReporting Monitor.Installer.GUI
Monitor.Installer.Internal
Monitor.Installer.Logic.Framework
Monitor.Installer.Logic.MQ.PIL Monitor.Installer.Logic.VcRedist2015x64.PIL
Monitor.Installer.Server.Nancy Monitor.Installer.Server.Shared
Monitor.Installer.ServerConsoleHost Monitor.Installer.ServerLibrary
Monitor.Installer.ServerServiceHost
Monitor.Installer.WiX.Common
Monitor.Installer.WiX
Monitor.Installer.WiX.Installer.Client Monitor.Installer.WiX.Installer
Monitor.Installer.WiX.Installer.Server Monitor.Installer.WiX.Installer.WebServer
Monitor.IntegrationTests.Helpers Monitor.Ioc
Monitor.M2M.MailExtractor
Monitor.Modules.Basic Monitor.Modules.Common
Monitor.Modules.Debug Monitor.Modules
Monitor.Modules.EDI Monitor.Modules.Gadgets
Monitor.Modules.Infrastructure
Monitor.Modules.Installation
Monitor.Modules.IntegrationTests Monitor.Modules.Inventory
Monitor.Modules.Manufacturing
Monitor.Modules.Purchase Monitor.Modules.Sales
Monitor.Modules.ThirdParty
Monitor.Modules.Web Monitor.Modules.Workshop
Monitor.MQ
Monitor.MQ.IntegrationTests
Monitor.MQ.Management
Monitor.MQ.Messages
Monitor.Persistence
Monitor.Persistence.MonitorDB
Monitor.Persistence.NHibernateAdapters.IntegrationTests
Monitor.Persistence.Shared
Monitor.RecipeCompiler
Monitor.RecipeCompilerRunner
Monitor.Scheduler
Monitor.Serialization.Binary Monitor.Serialization.Json.NewtonSoft
Monitor.Server.Console
Monitor.Server
Monitor.Server.Service Monitor.Server.Shared
Monitor.Sspi Monitor.SystemInformation
Monitor.Updater.Abstraction
Monitor.Updater.ConsoleHost Monitor.Updater
Monitor.Updater.ServiceHost Monitor.Updater.Tester
Monitor.Utils
Monitor.Utils.UnitTestExtensions
Monitor.Utils.UnitTestExtensionsTests
Monitor.Web.Common
Monitor.Web.ConsoleHost Monitor.Web.Server
Monitor.Web.ServiceControl Monitor.Web.ServiceHost
MonitorBackupInstallLogic.PIL
MonitorDatabaseMigrator
MonitorDatabaseMigrator.Test