From 03dc01c6560135d7d58e6a57fd368df6af66ba8c Mon Sep 17 00:00:00 2001 From: oliag Date: Thu, 27 Feb 2020 18:52:03 -0800 Subject: [PATCH 01/11] Add chapter 3 --- ...3-migrating-modern-desktop-applications.md | 332 ++++++++++++++++++ 1 file changed, 332 insertions(+) create mode 100644 docs/architecture/modernize-desktop/03-migrating-modern-desktop-applications.md diff --git a/docs/architecture/modernize-desktop/03-migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/03-migrating-modern-desktop-applications.md new file mode 100644 index 0000000000000..d5035e8754616 --- /dev/null +++ b/docs/architecture/modernize-desktop/03-migrating-modern-desktop-applications.md @@ -0,0 +1,332 @@ +--- +title: Migrating Modern Desktop Applications +description: Everything you need to know about the migration process for modern desktop applications. +ms.date: 09/16/2019 +--- + +# Migrating Modern Desktop Applications + +In this chapter, we are exploring the most common issues and challenges you can +face when migrating an existing application from .NET Framework to .NET Core. + +A complex desktop application does not work in isolation and needs some kind of +interaction with subsystems that may reside on the local machine or on a remote +server. It will probably need some kind of database to connect as a persistence +storage either local or remotely. With the raise of Internet and +service-oriented architectures, it’s extremely common to have your application +connected to some sort of service residing on a remote server or in the cloud. +You may need to access the machine file system to implement some functionality. +Alternatively, maybe you are using a piece of functionality that resides inside +a COM object outside your application which is a common scenario if, for +example, you are integrating Office assemblies in your app. + +Besides, there are differences in the surface of the APIs exposed by .NET +Framework and .NET Core and some parts of what is existing on .NET Framework is +no longer available on .NET Core, so it is important for you to know and take +into account when planning a migration. + +## Configuration files + +Configuration files offer the possibility to store sets of properties that are +read at runtime affecting the behavior of our apps like where to locate a +database or how many times to execute a loop. The beauty of this technique is +that you can modify some aspects of the application without the need to recode +and recompile. This comes in handy when for example the same app code runs on a +development environment with a certain set of configuration values and in +production with a different one. + +### Configuration on .NET Framework + +If you have a working .NET Framework desktop application chances are you have an +app.config file accessed through the AppSettings class from System.Configuration +namespace. + +Within the .NET Framework infrastructure there is a hierarchy of configuration +files that inherit properties from its parents. You can find a machine.config +that defines a bunch of properties and configuration sections that can be used +or overridden in any descendant configuration file. + +### Configuration on .NET Core + +In the .NET Core world there is no machine.config and although you can continue +to use the old fashioned System.Configuration you may consider to switch to the +modern Microsoft.Extensions.Configuration which offers a good amount of +enhancements. + +The configuration API supports the concept of configuration provider that +defines the source of data to be used to load the configuration. There are a +variety of built-in providers like in-memory .NET objects, INI files, JSON +files, XML files, command-line arguments, environment variables and encrypted +user store, or you can build your own. + +The new configuration allows a list of name-value pairs, which can be grouped +into a multi-level hierarchy. Any stored value maps to a string, and there is +built-in binding support that allows you to deserialize settings into a custom +POCO object. + +The ConfigurationBuilder object lets you add as many configuration providers you +may need for your application, using a precedence rule to resolve preference. +So, the last provider you add in your code will override the others. This is a +great feature for managing different environments for execution since you can +define different configurations for development, testing and production +environments, and managed them on a single function inside your code. + +### Migrating Configuration files + +You can remain using the old app.config XML files for configuration or proceed a +migration to benefit from the wonderful enhancements waiting for you on .NET +Core. + +To perform a migration from an old-style app.config to a new configuration file +you should choose between an XML format and a JSON format. In the case of XML, +the conversion is straight forward since the content is the same just a rename +to a file with XML extension. Then you need to migrate from AppSettings lines of +code to Configuration builder, but that should be very easy. + +In the case, you want to use a JSON format and you don’t want to migrate by hand +there is a tool called **dotnet-config2json** available on .NET Core that will +output a JSON configuration file from an old App.Config XML file. + +You may also encounter some issues when using configuration sections that where +defined in the machine.config. For example, consider this configuration: + +```xml + + + + + + + + + + + + +``` + +If you take this configuration to a .NET Core you will get an exception: + +Unrecognized configuration section system.diagnostics + +This is because that section and the assembly responsible for handling it was +defined in the machine.config which now does not exist. + +To easily fix the issue you can copy the section definition from your old +machine.config to your new configuration file: + +```xml + +
+ +``` + +## Accessing Databases + +Almost every desktop application needs some kind of database. For desktop is +common to find client-server architectures with a direct connection between the +desktop app and the database engine. These databases can be local or remote +depending of the need to share information between different users. + +From the code perspective there has been a lot of technologies and frameworks to +give the developer the possibility to connect, query and update a database. + +The most common examples of database you can find when talking about Windows +Desktop application are Microsoft Access and Microsoft SQL Server. If you have +more than 20 years of experience programming for the desktop the names, ODBC, +OLEDB, RDO, ADO and ADO.NET, LINQ and Entity Framework will sound familiar. + +### ODBC + +You can continue to use ODBC on .NET Core since Microsoft is providing the +`System.Data.Odbc` library compatible with .NET Standard 2.0. + +### OLE DB + +[OLE DB](https://msdn.microsoft.com/library/ms722784(v=vs.85).aspx) has +been a great way to access various data sources in a uniform manner, but it was +based on COM, which is a Windows-only technology, and as such was not the best +fit for a cross-platform technology such as .NET Core. It is also unsupported in +SQL Server versions 2014 and later. For those reasons, OLE DB will not be +supported by .NET Core. + +### ADO.NET + +You can still use ADO.NET from your existing desktop code on .NET Core. You will +just need to update some NuGet packages. + +### EF Core vs EF 6 + +There are two versions of Entity Framework, Entity Framework 6 and Entity +Framework Core. + +The latest technology released as part of the .NET Framework world is Entity +Framework, with 6.3 being the latest version. With the launch of .NET Core, +Microsoft also released a new data access stack based on Entity Framework and +called Entity Framework Core. + +You can use EF 6.3 and EF Core from both .NET Framework and .NET Core, so what +are the decision drivers to help to decide between the two? + +EF 6.3 will be the first version of EF 6 that can run on .NET Core and work +cross-platform. In fact, the main goal of this release is to facilitate +migrating existing applications that use EF 6 to .NET Core 3.0. + +EF Core was designed to provide a developer experience similar to EF6. Most of +the top-level APIs remain the same, so EF Core will feel familiar to developers +who have used EF6. + +Although compatible, there are differences on the implementation you should +check before making a decision. +() + +The recommendation is to use EF Core if: + +* The app needs the capabilities of .NET Core. +* EF Core supports all of the features that the app requires + +Consider using EF6 if both of the following conditions are true: + +* The app will run on Windows and the .NET Framework 4.0 or later. +* EF6 supports all of the features that the app requires. + +### **Relational databases** + +#### SQL Server + +SQL Server has been one of the databases of choice if you were developing for +the desktop some years ago. With the use of `System.Data.SqlClient` in .NET +Framework, you could access versions of SQL Server, which encapsulates +database-specific protocols. + +In .NET Core, you can find a new `SqlClient` fully compatible with the one +existing in the .NET Framework but located in the `Microsoft.Data.SqlClient` +library. You just have to add a dependency for this package and do some renaming +for the namespaces and everything should work as expected. + +#### Microsoft Access + +Microsoft Access and its Jet Database Engine has been used for years when the +sophisticated and more scalable SQL Server was not needed. You can still connect +to Microsoft Access using the `System.Data.Odbc` library. + +## Consuming services + +With the raise of service-oriented architectures, desktop applications begin to +evolve from a client-server model to the three-layer approach. In the +client-server approach a direct database connection is established from the +client holding the business logic usually inside a single EXE file. On the other +hand, the three-layer approach stablish an intermediate service layer +implementing business logic and database access allowing for better security, +scalability and reusability. Instead of working directly with datasets of data, +the layer approach relies in a set of services implementing contracts and types +objects as a way to implement data transfer. + +If you have a desktop application using a WCF service and you want to migrate it +to .NET Core, there are some things to consider. + +The first thing is how to resolve the configuration to access the service. +Because the configuration is different on .NET Core and you will need to make +some updates in your configuration file. + +Second, you will need to regenerate the service client with the new tools +present on Visual Studio 2019. In this step, you must consider activating the +generation of the synchronous operations to make the client compatible with your +existing code. + +If you find that after migration there are libraries you need that aren’t +present on .NET Core you can add a reference to Microsoft.Windows.Compatibility +and see if the missing functions are there. + +If you are using the WebRequest class to perform Web Service calls you may +encounter some differences on .NET Core. The recommendation is to use the +System.Net.Http.HttpClient instead. + +## Consuming a COM Object + +Currently there is no way to add a reference to a COM object from Visual Studio +2019 for using with .NET Core so you have to follow some manual steps modifying +the .csproj file for the project. + +You need to insert a COMReference structure inside the Project file like: + +```xml + + + {3050F1C5-98B5-11CF-BB82-00AA00BDCE0B}\ + 4 + 0 + 0 + primary + false + + +``` + +## **More things to consider** + +Several technologies available to .NET Framework libraries aren’t available for +use with .NET Core. If your code relies on some of these technologies, consider +the alternative approaches outlined below. + +The Windows Compatibility Pack provides access to APIs that were previously +available only for .NET Framework. It can be used from both .NET Core as well as +.NET Standard. + +For more information on API compatibility, the CoreFX team maintains a list of +behavioral changes/compat breaks and deprecated/legacy APIs at GitHub. +) + +### AppDomains + +Application domains (AppDomains) isolate apps from one another. AppDomains +require runtime support and are generally quite expensive. Creating additional +app domains is not supported. For code isolation, we recommend separate +processes or using containers as an alternative. For the dynamic loading of +assemblies, we recommend the new AssemblyLoadContext class. + +To make code migration from .NET Framework easier, .NET Core exposes some of +the AppDomain API surface. Some of the APIs function normally (for +example, AppDomain.UnhandledException), some members do nothing (for +example, SetCachePath), and some of them throw +PlatformNotSupportedException (for example, CreateDomain). + +### Remoting + +.NET Remoting was used for cross-AppDomain communication, which is no longer +supported. Also, Remoting requires runtime support, which is expensive to +maintain. For these reasons, .NET Remoting is not supported on .NET Core. + +For communication across processes you should consider inter-process +communication (IPC) mechanisms as an alternative to Remoting, such as +the System.IO.Pipes or the MemoryMappedFile class. + +Across machines, use a network-based solution as an alternative. Preferably, use +a low-overhead plain text protocol, such as HTTP. The Kestrel web server, the +web server used by ASP.NET Core, is an option here. + +### Code Access Security + +Sandboxing, which relies on the runtime or the framework to constrain which +resources a managed application or library uses or runs is not supported on .NET +Core. + +Use security boundaries provided by the operating system, such as +virtualization, containers, or user accounts for running processes with the +minimum set of privileges. + +### Security Transparency + +Similar to CAS (Code Access Security), Security Transparency separates sandboxed +code from security critical code in a declarative fashion but is no longer +supported as a security boundary. + +Use security boundaries provided by the operating system, such as +virtualization, containers, or user accounts for running processes with the +least set of privileges. From 336d955f4b834d63fb9c98b85e20783cfae9bbdb Mon Sep 17 00:00:00 2001 From: oliag Date: Thu, 27 Feb 2020 19:18:40 -0800 Subject: [PATCH 02/11] Replace numbers with chapter names --- ...p-applications.md => migrating-modern-desktop-applications.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/architecture/modernize-desktop/{03-migrating-modern-desktop-applications.md => migrating-modern-desktop-applications.md} (100%) diff --git a/docs/architecture/modernize-desktop/03-migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md similarity index 100% rename from docs/architecture/modernize-desktop/03-migrating-modern-desktop-applications.md rename to docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md From 952c8f5142063867cf58c5c52ab7f06ed65cae65 Mon Sep 17 00:00:00 2001 From: oliag Date: Fri, 6 Mar 2020 22:31:58 -0800 Subject: [PATCH 03/11] Update to 83 Acrolinx score --- .../migrating-modern-desktop-applications.md | 59 +++++++++---------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md index d5035e8754616..0a9b369724199 100644 --- a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md +++ b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md @@ -13,11 +13,11 @@ A complex desktop application does not work in isolation and needs some kind of interaction with subsystems that may reside on the local machine or on a remote server. It will probably need some kind of database to connect as a persistence storage either local or remotely. With the raise of Internet and -service-oriented architectures, it’s extremely common to have your application +service-oriented architectures, it's common to have your application connected to some sort of service residing on a remote server or in the cloud. You may need to access the machine file system to implement some functionality. Alternatively, maybe you are using a piece of functionality that resides inside -a COM object outside your application which is a common scenario if, for +a COM object outside your application that is a common scenario if, for example, you are integrating Office assemblies in your app. Besides, there are differences in the surface of the APIs exposed by .NET @@ -31,7 +31,7 @@ Configuration files offer the possibility to store sets of properties that are read at runtime affecting the behavior of our apps like where to locate a database or how many times to execute a loop. The beauty of this technique is that you can modify some aspects of the application without the need to recode -and recompile. This comes in handy when for example the same app code runs on a +and recompile. This comes in handy when, for example, the same app code runs on a development environment with a certain set of configuration values and in production with a different one. @@ -41,17 +41,16 @@ If you have a working .NET Framework desktop application chances are you have an app.config file accessed through the AppSettings class from System.Configuration namespace. -Within the .NET Framework infrastructure there is a hierarchy of configuration +Within the .NET Framework infrastructure, there is a hierarchy of configuration files that inherit properties from its parents. You can find a machine.config that defines a bunch of properties and configuration sections that can be used or overridden in any descendant configuration file. ### Configuration on .NET Core -In the .NET Core world there is no machine.config and although you can continue +In the .NET Core world, there is no machine.config and although you can continue to use the old fashioned System.Configuration you may consider to switch to the -modern Microsoft.Extensions.Configuration which offers a good amount of -enhancements. +modern Microsoft.Extensions.Configuration, which offers a good number of enhancements. The configuration API supports the concept of configuration provider that defines the source of data to be used to load the configuration. There are a @@ -77,17 +76,17 @@ You can remain using the old app.config XML files for configuration or proceed a migration to benefit from the wonderful enhancements waiting for you on .NET Core. -To perform a migration from an old-style app.config to a new configuration file -you should choose between an XML format and a JSON format. In the case of XML, -the conversion is straight forward since the content is the same just a rename -to a file with XML extension. Then you need to migrate from AppSettings lines of -code to Configuration builder, but that should be very easy. +To perform a migration from an old-style app.config to a new configuration file, +you should choose between an XML format and a JSON format. For XML, the +conversion is straight forward since the content is the same just a rename to a +file with XML extension. Then you need to migrate from AppSettings lines of code +to Configuration builder, but that should be easy. -In the case, you want to use a JSON format and you don’t want to migrate by hand +In the case, you want to use a JSON format and you don't want to migrate by hand there is a tool called **dotnet-config2json** available on .NET Core that will output a JSON configuration file from an old App.Config XML file. -You may also encounter some issues when using configuration sections that where +You may also encounter some issues when using configuration sections that were defined in the machine.config. For example, consider this configuration: ```xml @@ -109,14 +108,14 @@ defined in the machine.config. For example, consider this configuration: ``` -If you take this configuration to a .NET Core you will get an exception: +If you take this configuration to a .NET Core, you will get an exception: Unrecognized configuration section system.diagnostics This is because that section and the assembly responsible for handling it was -defined in the machine.config which now does not exist. +defined in the machine.config, which now does not exist. -To easily fix the issue you can copy the section definition from your old +To easily fix the issue, you can copy the section definition from your old machine.config to your new configuration file: ```xml @@ -132,10 +131,10 @@ machine.config to your new configuration file: Almost every desktop application needs some kind of database. For desktop is common to find client-server architectures with a direct connection between the desktop app and the database engine. These databases can be local or remote -depending of the need to share information between different users. +depending on the need to share information between different users. -From the code perspective there has been a lot of technologies and frameworks to -give the developer the possibility to connect, query and update a database. +From the code perspective, there have been many technologies and frameworks to +give the developer the possibility to connect, query, and update a database. The most common examples of database you can find when talking about Windows Desktop application are Microsoft Access and Microsoft SQL Server. If you have @@ -212,7 +211,7 @@ for the namespaces and everything should work as expected. #### Microsoft Access -Microsoft Access and its Jet Database Engine has been used for years when the +have been used for years when the sophisticated and more scalable SQL Server was not needed. You can still connect to Microsoft Access using the `System.Data.Odbc` library. @@ -220,11 +219,11 @@ to Microsoft Access using the `System.Data.Odbc` library. With the raise of service-oriented architectures, desktop applications begin to evolve from a client-server model to the three-layer approach. In the -client-server approach a direct database connection is established from the +client-server approach, a direct database connection is established from the client holding the business logic usually inside a single EXE file. On the other -hand, the three-layer approach stablish an intermediate service layer +hand, the three-layer approach establishes an intermediate service layer implementing business logic and database access allowing for better security, -scalability and reusability. Instead of working directly with datasets of data, +scalability, and reusability. Instead of working directly with datasets of data, the layer approach relies in a set of services implementing contracts and types objects as a way to implement data transfer. @@ -240,18 +239,18 @@ present on Visual Studio 2019. In this step, you must consider activating the generation of the synchronous operations to make the client compatible with your existing code. -If you find that after migration there are libraries you need that aren’t +If you find that after migration, there are libraries you need that aren't present on .NET Core you can add a reference to Microsoft.Windows.Compatibility and see if the missing functions are there. -If you are using the WebRequest class to perform Web Service calls you may +If you are using the WebRequest class to perform Web Service calls, you may encounter some differences on .NET Core. The recommendation is to use the System.Net.Http.HttpClient instead. ## Consuming a COM Object Currently there is no way to add a reference to a COM object from Visual Studio -2019 for using with .NET Core so you have to follow some manual steps modifying +2019 for using with .NET Core so you have to follow some manual steps and modify the .csproj file for the project. You need to insert a COMReference structure inside the Project file like: @@ -271,7 +270,7 @@ You need to insert a COMReference structure inside the Project file like: ## **More things to consider** -Several technologies available to .NET Framework libraries aren’t available for +Several technologies available to .NET Framework libraries aren't available for use with .NET Core. If your code relies on some of these technologies, consider the alternative approaches outlined below. @@ -286,7 +285,7 @@ behavioral changes/compat breaks and deprecated/legacy APIs at GitHub. ### AppDomains Application domains (AppDomains) isolate apps from one another. AppDomains -require runtime support and are generally quite expensive. Creating additional +require runtime support and are expensive. Creating additional app domains is not supported. For code isolation, we recommend separate processes or using containers as an alternative. For the dynamic loading of assemblies, we recommend the new AssemblyLoadContext class. @@ -303,7 +302,7 @@ PlatformNotSupportedException (for example, CreateDomain). supported. Also, Remoting requires runtime support, which is expensive to maintain. For these reasons, .NET Remoting is not supported on .NET Core. -For communication across processes you should consider inter-process +For communication across processes, you should consider inter-process communication (IPC) mechanisms as an alternative to Remoting, such as the System.IO.Pipes or the MemoryMappedFile class. From 82166424b11f8be7ec98b6525cd4fc7175fc7982 Mon Sep 17 00:00:00 2001 From: Olia Gavrysh <31997351+OliaG@users.noreply.github.com> Date: Tue, 7 Apr 2020 15:08:53 -0700 Subject: [PATCH 04/11] Apply suggestions from code review Co-Authored-By: Maira Wenzel --- .../migrating-modern-desktop-applications.md | 200 +++++++++--------- 1 file changed, 105 insertions(+), 95 deletions(-) diff --git a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md index 0a9b369724199..7e93efa14fa6d 100644 --- a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md +++ b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md @@ -6,88 +6,98 @@ ms.date: 09/16/2019 # Migrating Modern Desktop Applications -In this chapter, we are exploring the most common issues and challenges you can +In this chapter, we're exploring the most common issues and challenges you can face when migrating an existing application from .NET Framework to .NET Core. -A complex desktop application does not work in isolation and needs some kind of +A complex desktop application doesn't work in isolation and needs some kind of interaction with subsystems that may reside on the local machine or on a remote server. It will probably need some kind of database to connect as a persistence storage either local or remotely. With the raise of Internet and service-oriented architectures, it's common to have your application connected to some sort of service residing on a remote server or in the cloud. You may need to access the machine file system to implement some functionality. -Alternatively, maybe you are using a piece of functionality that resides inside +Alternatively, maybe you're using a piece of functionality that resides inside a COM object outside your application that is a common scenario if, for -example, you are integrating Office assemblies in your app. +example, you're integrating Office assemblies in your app. -Besides, there are differences in the surface of the APIs exposed by .NET +Besides, there are differences in the API surface that is exposed by .NET Framework and .NET Core and some parts of what is existing on .NET Framework is -no longer available on .NET Core, so it is important for you to know and take +no longer available on .NET Core. So, it's important for you to know and take them into account when planning a migration. ## Configuration files Configuration files offer the possibility to store sets of properties that are -read at runtime affecting the behavior of our apps like where to locate a +read at run time and affect the behavior of our apps, such as where to locate a database or how many times to execute a loop. The beauty of this technique is that you can modify some aspects of the application without the need to recode -and recompile. This comes in handy when, for example, the same app code runs on a +and recompile. This comes in handy when, for example, the same app code runs on a development environment with a certain set of configuration values and in production with a different one. ### Configuration on .NET Framework -If you have a working .NET Framework desktop application chances are you have an -app.config file accessed through the AppSettings class from System.Configuration -namespace. +If you have a working .NET Framework desktop application, chances are you have an +*app.config* file accessed through the class from +the `System.Configuration` namespace. -Within the .NET Framework infrastructure, there is a hierarchy of configuration -files that inherit properties from its parents. You can find a machine.config -that defines a bunch of properties and configuration sections that can be used +Within the .NET Framework infrastructure, there's a hierarchy of configuration +files that inherit properties from its parents. You can find a *machine.config* file +that defines many properties and configuration sections that can be used or overridden in any descendant configuration file. ### Configuration on .NET Core -In the .NET Core world, there is no machine.config and although you can continue -to use the old fashioned System.Configuration you may consider to switch to the -modern Microsoft.Extensions.Configuration, which offers a good number of enhancements. +In the .NET Core world, there's no *machine.config* file. And even though you can continue +to use the old fashioned namespace, you may consider switching to the +modern , which offers a good number of enhancements. -The configuration API supports the concept of configuration provider that -defines the source of data to be used to load the configuration. There are a -variety of built-in providers like in-memory .NET objects, INI files, JSON -files, XML files, command-line arguments, environment variables and encrypted -user store, or you can build your own. +The configuration API supports the concept of configuration provider, which +defines the data source to be used to load the configuration. There are a +variety of built-in providers, such as: -The new configuration allows a list of name-value pairs, which can be grouped -into a multi-level hierarchy. Any stored value maps to a string, and there is +- In-memory .NET objects +- INI files +- JSON files +- XML files +- Command-line arguments +- Environment variables +- Encrypted user store + + Or you can build your own. + +The new configuration allows a list of name-value pairs that can be grouped +into a multi-level hierarchy. Any stored value maps to a string, and there's built-in binding support that allows you to deserialize settings into a custom -POCO object. +plain old CLR object (POCO) object. -The ConfigurationBuilder object lets you add as many configuration providers you +The object lets you add as many configuration providers you may need for your application, using a precedence rule to resolve preference. So, the last provider you add in your code will override the others. This is a great feature for managing different environments for execution since you can define different configurations for development, testing and production -environments, and managed them on a single function inside your code. +environments, and manage them on a single function inside your code. ### Migrating Configuration files -You can remain using the old app.config XML files for configuration or proceed a -migration to benefit from the wonderful enhancements waiting for you on .NET -Core. +You can continue to use your existing app.config XML file. However, you could take this opportunity +to migrate your configuration to benefit from the several enhancements made on .NET Core. -To perform a migration from an old-style app.config to a new configuration file, -you should choose between an XML format and a JSON format. For XML, the -conversion is straight forward since the content is the same just a rename to a -file with XML extension. Then you need to migrate from AppSettings lines of code +To migrate from an old-style *app.config* to a new configuration file, +you should choose between an XML format and a JSON format. + +If you choose XML, the +conversion is straightforward. Since the content is the same, just rename the *app.config* file +to a file with XML extension. Then migrate from AppSettings lines of code to Configuration builder, but that should be easy. -In the case, you want to use a JSON format and you don't want to migrate by hand -there is a tool called **dotnet-config2json** available on .NET Core that will -output a JSON configuration file from an old App.Config XML file. -You may also encounter some issues when using configuration sections that were -defined in the machine.config. For example, consider this configuration: +If you want to use a JSON format and you don't want to migrate by hand, +there's a tool called [dotnet-config2json](https://www.nuget.org/packages/dotnet-config2json/) available on .NET Core that +can convert an *app.config* file to a JSON configuration file. + +You may also come across some issues when using configuration sections that were +defined in the *machine.config* file. For example, consider the following configuration: ```xml @@ -108,12 +118,12 @@ defined in the machine.config. For example, consider this configuration: ``` -If you take this configuration to a .NET Core, you will get an exception: +If you take this configuration to a .NET Core, you'll get an exception: Unrecognized configuration section system.diagnostics -This is because that section and the assembly responsible for handling it was -defined in the machine.config, which now does not exist. +This exception occurs because that section and the assembly responsible for handling that section was +defined in the *machine.config* file, which now doesn't exist. To easily fix the issue, you can copy the section definition from your old machine.config to your new configuration file: @@ -128,7 +138,7 @@ machine.config to your new configuration file: ## Accessing Databases -Almost every desktop application needs some kind of database. For desktop is +Almost every desktop application needs some kind of database. For desktop, it's common to find client-server architectures with a direct connection between the desktop app and the database engine. These databases can be local or remote depending on the need to share information between different users. @@ -138,8 +148,8 @@ give the developer the possibility to connect, query, and update a database. The most common examples of database you can find when talking about Windows Desktop application are Microsoft Access and Microsoft SQL Server. If you have -more than 20 years of experience programming for the desktop the names, ODBC, -OLEDB, RDO, ADO and ADO.NET, LINQ and Entity Framework will sound familiar. +more than 20 years of experience programming for the desktop, names like ODBC, +OLEDB, RDO, ADO, ADO.NET, LINQ, and Entity Framework will sound familiar. ### ODBC @@ -149,33 +159,33 @@ You can continue to use ODBC on .NET Core since Microsoft is providing the ### OLE DB [OLE DB](https://msdn.microsoft.com/library/ms722784(v=vs.85).aspx) has -been a great way to access various data sources in a uniform manner, but it was -based on COM, which is a Windows-only technology, and as such was not the best -fit for a cross-platform technology such as .NET Core. It is also unsupported in -SQL Server versions 2014 and later. For those reasons, OLE DB will not be +been a great way to access various data sources in a uniform manner. But it was +based on COM, which is a Windows-only technology, and as such wasn't the best +fit for a cross-platform technology such as .NET Core. It's also unsupported in +SQL Server versions 2014 and later. For those reasons, OLE DB won't be supported by .NET Core. ### ADO.NET -You can still use ADO.NET from your existing desktop code on .NET Core. You will +You can still use ADO.NET from your existing desktop code on .NET Core. You just need to update some NuGet packages. -### EF Core vs EF 6 +### EF Core vs. EF6 -There are two versions of Entity Framework, Entity Framework 6 and Entity -Framework Core. +There are two currently supported versions of Entity Framework (EF), +Entity Framework 6 (EF6) and EF Core. The latest technology released as part of the .NET Framework world is Entity -Framework, with 6.3 being the latest version. With the launch of .NET Core, +Framework, with 6.4 being the latest version. With the launch of .NET Core, Microsoft also released a new data access stack based on Entity Framework and called Entity Framework Core. -You can use EF 6.3 and EF Core from both .NET Framework and .NET Core, so what +You can use EF 6.3 and EF Core from both .NET Framework and .NET Core. So, what are the decision drivers to help to decide between the two? -EF 6.3 will be the first version of EF 6 that can run on .NET Core and work -cross-platform. In fact, the main goal of this release is to facilitate -migrating existing applications that use EF 6 to .NET Core 3.0. +EF 6.3 is the first version of EF 6 that can run on .NET Core and work +cross-platform. In fact, the main goal of this release is to make it easier +to migrate existing applications that use EF6 to .NET Core. EF Core was designed to provide a developer experience similar to EF6. Most of the top-level APIs remain the same, so EF Core will feel familiar to developers @@ -183,41 +193,41 @@ who have used EF6. Although compatible, there are differences on the implementation you should check before making a decision. -() +For more information, see [Compare EF Core & EF6](/ef/efcore-and-ef6/). The recommendation is to use EF Core if: * The app needs the capabilities of .NET Core. -* EF Core supports all of the features that the app requires +* EF Core supports all of the features that the app requires. Consider using EF6 if both of the following conditions are true: -* The app will run on Windows and the .NET Framework 4.0 or later. +* The app will run on Windows and .NET Framework 4.0 or later. * EF6 supports all of the features that the app requires. -### **Relational databases** +### Relational databases #### SQL Server SQL Server has been one of the databases of choice if you were developing for -the desktop some years ago. With the use of `System.Data.SqlClient` in .NET +the desktop some years ago. With the use of in .NET Framework, you could access versions of SQL Server, which encapsulates database-specific protocols. -In .NET Core, you can find a new `SqlClient` fully compatible with the one -existing in the .NET Framework but located in the `Microsoft.Data.SqlClient` -library. You just have to add a dependency for this package and do some renaming +In .NET Core, you can find a new `SqlClient` class, fully compatible with the one +existing in the .NET Framework but located in the +library. You just have to add a dependency for this [NuGet package}(https://www.nuget.org/packages/Microsoft.Data.SqlClient/) and do some renaming for the namespaces and everything should work as expected. #### Microsoft Access -have been used for years when the -sophisticated and more scalable SQL Server was not needed. You can still connect -to Microsoft Access using the `System.Data.Odbc` library. +Microsoft Access has been used for years when the +sophisticated and more scalable SQL Server wasn't needed. You can still connect +to Microsoft Access using the library. ## Consuming services -With the raise of service-oriented architectures, desktop applications begin to +With the raise of service-oriented architectures, desktop applications began to evolve from a client-server model to the three-layer approach. In the client-server approach, a direct database connection is established from the client holding the business logic usually inside a single EXE file. On the other @@ -231,29 +241,29 @@ If you have a desktop application using a WCF service and you want to migrate it to .NET Core, there are some things to consider. The first thing is how to resolve the configuration to access the service. -Because the configuration is different on .NET Core and you will need to make +Because the configuration is different on .NET Core, you'll need to make some updates in your configuration file. -Second, you will need to regenerate the service client with the new tools +Second, you'll need to regenerate the service client with the new tools present on Visual Studio 2019. In this step, you must consider activating the generation of the synchronous operations to make the client compatible with your existing code. If you find that after migration, there are libraries you need that aren't -present on .NET Core you can add a reference to Microsoft.Windows.Compatibility -and see if the missing functions are there. +present on .NET Core you can add a reference to the [Microsoft.Windows.Compatibility](https://www.nuget.org/packages/Microsoft.Windows.Compatibility) +NuGet package and see if the missing functions are there. -If you are using the WebRequest class to perform Web Service calls, you may -encounter some differences on .NET Core. The recommendation is to use the +If you're using the class to perform web service calls, you may +find some differences on .NET Core. The recommendation is to use the System.Net.Http.HttpClient instead. ## Consuming a COM Object -Currently there is no way to add a reference to a COM object from Visual Studio -2019 for using with .NET Core so you have to follow some manual steps and modify -the .csproj file for the project. +Currently, there's no way to add a reference to a COM object from Visual Studio +2019 to use with .NET Core. So, you have to follow some manual steps and modify +the *.csproj* file for the project. -You need to insert a COMReference structure inside the Project file like: +Insert a `COMReference` structure inside the project file like in the following example: ```xml @@ -268,13 +278,13 @@ You need to insert a COMReference structure inside the Project file like: ``` -## **More things to consider** +## More things to consider Several technologies available to .NET Framework libraries aren't available for -use with .NET Core. If your code relies on some of these technologies, consider -the alternative approaches outlined below. +.NET Core. If your code relies on some of these technologies, consider +the alternative approaches outlined in this section. -The Windows Compatibility Pack provides access to APIs that were previously +The [Windows Compatibility Pack](../../core/porting/windows-compat-pack.md) provides access to APIs that were previously available only for .NET Framework. It can be used from both .NET Core as well as .NET Standard. @@ -286,34 +296,34 @@ behavioral changes/compat breaks and deprecated/legacy APIs at GitHub. Application domains (AppDomains) isolate apps from one another. AppDomains require runtime support and are expensive. Creating additional -app domains is not supported. For code isolation, we recommend separate +app domains isn't supported. For code isolation, we recommend separate processes or using containers as an alternative. For the dynamic loading of -assemblies, we recommend the new AssemblyLoadContext class. +assemblies, we recommend the new  class. To make code migration from .NET Framework easier, .NET Core exposes some of the AppDomain API surface. Some of the APIs function normally (for -example, AppDomain.UnhandledException), some members do nothing (for -example, SetCachePath), and some of them throw -PlatformNotSupportedException (for example, CreateDomain). +example, ), some members do nothing (for +example, ), and some of them throw + (for example, ). ### Remoting .NET Remoting was used for cross-AppDomain communication, which is no longer supported. Also, Remoting requires runtime support, which is expensive to -maintain. For these reasons, .NET Remoting is not supported on .NET Core. +maintain. For these reasons, .NET Remoting isn't supported on .NET Core. For communication across processes, you should consider inter-process communication (IPC) mechanisms as an alternative to Remoting, such as -the System.IO.Pipes or the MemoryMappedFile class. +the or the class. Across machines, use a network-based solution as an alternative. Preferably, use -a low-overhead plain text protocol, such as HTTP. The Kestrel web server, the +a low-overhead plaintext protocol, such as HTTP. The Kestrel web server, the web server used by ASP.NET Core, is an option here. -### Code Access Security +### Code Access Security (CAS) Sandboxing, which relies on the runtime or the framework to constrain which -resources a managed application or library uses or runs is not supported on .NET +resources a managed application or library uses or runs isn't supported on .NET Core. Use security boundaries provided by the operating system, such as @@ -322,7 +332,7 @@ minimum set of privileges. ### Security Transparency -Similar to CAS (Code Access Security), Security Transparency separates sandboxed +Similar to CAS, Security Transparency separates sandboxed code from security critical code in a declarative fashion but is no longer supported as a security boundary. From 83d54a303271c36e6cb9a742be6a1e7da4fe2e04 Mon Sep 17 00:00:00 2001 From: Olia Gavrysh <31997351+OliaG@users.noreply.github.com> Date: Tue, 7 Apr 2020 15:13:24 -0700 Subject: [PATCH 05/11] Update migrating-modern-desktop-applications.md --- .../modernize-desktop/migrating-modern-desktop-applications.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md index 7e93efa14fa6d..6892baa140e47 100644 --- a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md +++ b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md @@ -88,8 +88,7 @@ you should choose between an XML format and a JSON format. If you choose XML, the conversion is straightforward. Since the content is the same, just rename the *app.config* file -to a file with XML extension. Then migrate from AppSettings lines of code -to Configuration builder, but that should be easy. +to a file with XML extension. Then, change the code that references AppSettings to use the ConfigurationBuilder class. That should be an easy change. If you want to use a JSON format and you don't want to migrate by hand, From 24abfcd002394bd3fd51a7123cd3009e28c47bd7 Mon Sep 17 00:00:00 2001 From: Olia Gavrysh <31997351+OliaG@users.noreply.github.com> Date: Tue, 7 Apr 2020 15:16:21 -0700 Subject: [PATCH 06/11] Update migrating-modern-desktop-applications.md --- .../modernize-desktop/migrating-modern-desktop-applications.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md index 6892baa140e47..a693727a65ca6 100644 --- a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md +++ b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md @@ -90,7 +90,6 @@ If you choose XML, the conversion is straightforward. Since the content is the same, just rename the *app.config* file to a file with XML extension. Then, change the code that references AppSettings to use the ConfigurationBuilder class. That should be an easy change. - If you want to use a JSON format and you don't want to migrate by hand, there's a tool called [dotnet-config2json](https://www.nuget.org/packages/dotnet-config2json/) available on .NET Core that can convert an *app.config* file to a JSON configuration file. From 8d6d69faadb6006a0cc36fa5acae93495effa0e1 Mon Sep 17 00:00:00 2001 From: oliag Date: Fri, 10 Apr 2020 11:48:23 -0700 Subject: [PATCH 07/11] Remove trailing spaces --- .../migrating-modern-desktop-applications.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md index a693727a65ca6..137f906549e84 100644 --- a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md +++ b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md @@ -38,8 +38,7 @@ production with a different one. ### Configuration on .NET Framework If you have a working .NET Framework desktop application, chances are you have an -*app.config* file accessed through the class from -the `System.Configuration` namespace. +*app.config* file accessed through the class from the `System.Configuration` namespace. Within the .NET Framework infrastructure, there's a hierarchy of configuration files that inherit properties from its parents. You can find a *machine.config* file @@ -80,14 +79,12 @@ environments, and manage them on a single function inside your code. ### Migrating Configuration files -You can continue to use your existing app.config XML file. However, you could take this opportunity -to migrate your configuration to benefit from the several enhancements made on .NET Core. +You can continue to use your existing app.config XML file. However, you could take this opportunity to migrate your configuration to benefit from the several enhancements made on .NET Core. To migrate from an old-style *app.config* to a new configuration file, -you should choose between an XML format and a JSON format. +you should choose between an XML format and a JSON format. -If you choose XML, the -conversion is straightforward. Since the content is the same, just rename the *app.config* file +If you choose XML, the conversion is straightforward. Since the content is the same, just rename the *app.config* file to a file with XML extension. Then, change the code that references AppSettings to use the ConfigurationBuilder class. That should be an easy change. If you want to use a JSON format and you don't want to migrate by hand, @@ -170,8 +167,7 @@ just need to update some NuGet packages. ### EF Core vs. EF6 -There are two currently supported versions of Entity Framework (EF), -Entity Framework 6 (EF6) and EF Core. +There are two currently supported versions of Entity Framework (EF), Entity Framework 6 (EF6) and EF Core. The latest technology released as part of the .NET Framework world is Entity Framework, with 6.4 being the latest version. With the launch of .NET Core, From 96469474d4b74c7b9a8f44bbfd39a00c7e86e10c Mon Sep 17 00:00:00 2001 From: Olia Gavrysh <31997351+OliaG@users.noreply.github.com> Date: Thu, 23 Apr 2020 19:10:35 -0700 Subject: [PATCH 08/11] Apply suggestions from code review Co-Authored-By: Maira Wenzel --- .../migrating-modern-desktop-applications.md | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md index 137f906549e84..0309af39d29f9 100644 --- a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md +++ b/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md @@ -12,17 +12,17 @@ face when migrating an existing application from .NET Framework to .NET Core. A complex desktop application doesn't work in isolation and needs some kind of interaction with subsystems that may reside on the local machine or on a remote server. It will probably need some kind of database to connect as a persistence -storage either local or remotely. With the raise of Internet and +storage either locally or remotely. With the raise of Internet and service-oriented architectures, it's common to have your application connected to some sort of service residing on a remote server or in the cloud. You may need to access the machine file system to implement some functionality. Alternatively, maybe you're using a piece of functionality that resides inside -a COM object outside your application that is a common scenario if, for +a COM object outside your application, which is a common scenario if, for example, you're integrating Office assemblies in your app. Besides, there are differences in the API surface that is exposed by .NET -Framework and .NET Core and some parts of what is existing on .NET Framework is -no longer available on .NET Core. So, it's important for you to know and take them +Framework and .NET Core, and some features that are available on .NET Framework +aren't available on .NET Core. So, it's important for you to know and take them into account when planning a migration. ## Configuration files @@ -52,8 +52,8 @@ to use the old fashioned namespace, you may consider modern , which offers a good number of enhancements. The configuration API supports the concept of configuration provider, which -defines the data source to be used to load the configuration. There are a -variety of built-in providers, such as: +defines the data source to be used to load the configuration. There are different +kinds of built-in providers, such as: - In-memory .NET objects - INI files @@ -85,7 +85,7 @@ To migrate from an old-style *app.config* to a new configuration file, you should choose between an XML format and a JSON format. If you choose XML, the conversion is straightforward. Since the content is the same, just rename the *app.config* file -to a file with XML extension. Then, change the code that references AppSettings to use the ConfigurationBuilder class. That should be an easy change. +to a file with XML extension. Then, change the code that references AppSettings to use the `ConfigurationBuilder` class. This change should be easy. If you want to use a JSON format and you don't want to migrate by hand, there's a tool called [dotnet-config2json](https://www.nuget.org/packages/dotnet-config2json/) available on .NET Core that @@ -177,7 +177,7 @@ called Entity Framework Core. You can use EF 6.3 and EF Core from both .NET Framework and .NET Core. So, what are the decision drivers to help to decide between the two? -EF 6.3 is the first version of EF 6 that can run on .NET Core and work +EF 6.3 is the first version of EF6 that can run on .NET Core and work cross-platform. In fact, the main goal of this release is to make it easier to migrate existing applications that use EF6 to .NET Core. @@ -210,8 +210,8 @@ database-specific protocols. In .NET Core, you can find a new `SqlClient` class, fully compatible with the one existing in the .NET Framework but located in the -library. You just have to add a dependency for this [NuGet package}(https://www.nuget.org/packages/Microsoft.Data.SqlClient/) and do some renaming -for the namespaces and everything should work as expected. +library. You just have to add a reference to the [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient/) +NuGet package and do some renaming for the namespaces and everything should work as expected. #### Microsoft Access @@ -243,8 +243,8 @@ present on Visual Studio 2019. In this step, you must consider activating the generation of the synchronous operations to make the client compatible with your existing code. -If you find that after migration, there are libraries you need that aren't -present on .NET Core you can add a reference to the [Microsoft.Windows.Compatibility](https://www.nuget.org/packages/Microsoft.Windows.Compatibility) +After the migration, if you find that there are libraries you need that aren't +present on .NET Core, you can add a reference to the [Microsoft.Windows.Compatibility](https://www.nuget.org/packages/Microsoft.Windows.Compatibility) NuGet package and see if the missing functions are there. If you're using the class to perform web service calls, you may @@ -254,8 +254,7 @@ System.Net.Http.HttpClient instead. ## Consuming a COM Object Currently, there's no way to add a reference to a COM object from Visual Studio -2019 to use with .NET Core. So, you have to follow some manual steps and modify -the *.csproj* file for the project. +2019 to use with .NET Core. So, you have to manually modify the project file. Insert a `COMReference` structure inside the project file like in the following example: @@ -279,8 +278,7 @@ Several technologies available to .NET Framework libraries aren't available for the alternative approaches outlined in this section. The [Windows Compatibility Pack](../../core/porting/windows-compat-pack.md) provides access to APIs that were previously -available only for .NET Framework. It can be used from both .NET Core as well as -.NET Standard. +available only for .NET Framework. It can be used on .NET Core and .NET Standard projects. For more information on API compatibility, the CoreFX team maintains a list of behavioral changes/compat breaks and deprecated/legacy APIs at GitHub. @@ -320,7 +318,7 @@ Sandboxing, which relies on the runtime or the framework to constrain which resources a managed application or library uses or runs isn't supported on .NET Core. -Use security boundaries provided by the operating system, such as +Use security boundaries that are provided by the operating system, such as virtualization, containers, or user accounts for running processes with the minimum set of privileges. @@ -330,6 +328,6 @@ Similar to CAS, Security Transparency separates sandboxed code from security critical code in a declarative fashion but is no longer supported as a security boundary. -Use security boundaries provided by the operating system, such as +Use security boundaries that are provided by the operating system, such as virtualization, containers, or user accounts for running processes with the least set of privileges. From 65f0c8b11f3725620cb6f9ebd491723c4e2950b5 Mon Sep 17 00:00:00 2001 From: oliag Date: Thu, 23 Apr 2020 19:37:45 -0700 Subject: [PATCH 09/11] Address comments --- ...desktop-applications.md => migrate-modern-applications.md} | 4 ++++ 1 file changed, 4 insertions(+) rename docs/architecture/modernize-desktop/{migrating-modern-desktop-applications.md => migrate-modern-applications.md} (99%) diff --git a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md b/docs/architecture/modernize-desktop/migrate-modern-applications.md similarity index 99% rename from docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md rename to docs/architecture/modernize-desktop/migrate-modern-applications.md index 0309af39d29f9..b371e66e750e9 100644 --- a/docs/architecture/modernize-desktop/migrating-modern-desktop-applications.md +++ b/docs/architecture/modernize-desktop/migrate-modern-applications.md @@ -331,3 +331,7 @@ supported as a security boundary. Use security boundaries that are provided by the operating system, such as virtualization, containers, or user accounts for running processes with the least set of privileges. + +>[!div class="step-by-step"] +>[Previous](whats-new-dotnet-core.md ) +>[Next](windows-migration.md) From 183bc297c270c815cccca863da4a9ef8ad0b354f Mon Sep 17 00:00:00 2001 From: Maira Wenzel Date: Sun, 26 Apr 2020 12:36:24 -0700 Subject: [PATCH 10/11] fix linting errors --- .../modernize-desktop/migrate-modern-applications.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/architecture/modernize-desktop/migrate-modern-applications.md b/docs/architecture/modernize-desktop/migrate-modern-applications.md index b371e66e750e9..8ebdc14eccf98 100644 --- a/docs/architecture/modernize-desktop/migrate-modern-applications.md +++ b/docs/architecture/modernize-desktop/migrate-modern-applications.md @@ -21,7 +21,7 @@ a COM object outside your application, which is a common scenario if, for example, you're integrating Office assemblies in your app. Besides, there are differences in the API surface that is exposed by .NET -Framework and .NET Core, and some features that are available on .NET Framework +Framework and .NET Core, and some features that are available on .NET Framework aren't available on .NET Core. So, it's important for you to know and take them into account when planning a migration. @@ -210,7 +210,7 @@ database-specific protocols. In .NET Core, you can find a new `SqlClient` class, fully compatible with the one existing in the .NET Framework but located in the -library. You just have to add a reference to the [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient/) +library. You just have to add a reference to the [Microsoft.Data.SqlClient](https://www.nuget.org/packages/Microsoft.Data.SqlClient/) NuGet package and do some renaming for the namespaces and everything should work as expected. #### Microsoft Access @@ -254,7 +254,7 @@ System.Net.Http.HttpClient instead. ## Consuming a COM Object Currently, there's no way to add a reference to a COM object from Visual Studio -2019 to use with .NET Core. So, you have to manually modify the project file. +2019 to use with .NET Core. So, you have to manually modify the project file. Insert a `COMReference` structure inside the project file like in the following example: From bef83b4278e3dc9b955e93e6cb905094fcfca1b8 Mon Sep 17 00:00:00 2001 From: Maira Wenzel Date: Sun, 26 Apr 2020 12:38:48 -0700 Subject: [PATCH 11/11] add missing comma --- .../modernize-desktop/migrate-modern-applications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture/modernize-desktop/migrate-modern-applications.md b/docs/architecture/modernize-desktop/migrate-modern-applications.md index 8ebdc14eccf98..1ae810805d561 100644 --- a/docs/architecture/modernize-desktop/migrate-modern-applications.md +++ b/docs/architecture/modernize-desktop/migrate-modern-applications.md @@ -315,7 +315,7 @@ web server used by ASP.NET Core, is an option here. ### Code Access Security (CAS) Sandboxing, which relies on the runtime or the framework to constrain which -resources a managed application or library uses or runs isn't supported on .NET +resources a managed application or library uses or runs, isn't supported on .NET Core. Use security boundaries that are provided by the operating system, such as