Hace unos días escribí un post sobre lo que es .NET Standard y sus diferencias contra una PCL. En este post explicaré el proceso para convertir un proyecto PCL existente a .NET Standard, debido a que en el post mencionado anteriormente ya explico de que depende la versión de .NET Standard a elegir y algunos conceptos relacionados a PCL en este solo me enfocare al proceso de conversión el cuál es muy simple.

Editar el archivo .csproj de la PCL

Simplemente debemos reemplazar TODO el contenido del archivo csproj del proyecto PCL por el siguiente (dependiendo de la versión de .NET Standard a utilizar puede variar el valor de “TargetFramework”)

<Project Sdk="Microsoft.NET.Sdk">
 <PropertyGroup>
    	<TargetFramework>netstandard2.0</TargetFramework>
 </PropertyGroup>
</Project>

 

 

Agregar las referencias a los paquetes NuGet

Para esto abre el archivo “packages.config” de tu proyecto, en este archivo están todas las referencias a los paquetes NuGet que utiliza el proyecto PCL.

El contenido del archivo es algo como esto:

<?xml version="1.0" encoding="utf-8"?>
<packages>
 <package id="HockeySDK.Xamarin" version="5.0.0" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Microsoft.Bcl" version="1.1.10" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Microsoft.Net.Http" version="2.2.29" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Newtonsoft.Json" version="10.0.3" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Plugin.Permissions" version="2.1.0" targetFramework="portable45-net45+win8+wpa81" />
 <package id="sqlite-net-pcl" version="1.4.118" targetFramework="portable45-net45+win8+wpa81" />
 <package id="SQLitePCLRaw.bundle_green" version="1.1.9" targetFramework="portable45-net45+win8+wpa81" />
 <package id="SQLitePCLRaw.core" version="1.1.9" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Xam.Plugin.Connectivity" version="3.0.3" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Xam.Plugin.Geolocator" version="4.1.3" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Xamarin.Forms" version="2.5.0.121934" targetFramework="portable45-net45+win8+wpa81" />
 <package id="Xamarin.Forms.Maps" version="2.5.0.121934" targetFramework="portable45-net45+win8+wpa81" />
</packages>

El siguiente paso es agregar cada paquete instalado al archivo .csproj  debajo de la etiqueta agregada en el paso anterior, en una sección como la que se muestra a continuación:

<ItemGroup>
  	<PackageReference Include="NombreDePaquete" Version="VersionDelPaquete" />
 </ItemGroup>

Para el archivo “packages.config” del ejemplo el resultado sería este:

<ItemGroup>
  <PackageReference Include="Microsoft.Bcl" Version="1.1.10" />
  <PackageReference Include="Microsoft.Bcl.Build"Version="1.0.21" />
  <PackageReference Include="Microsoft.Net.Http" Version="2.2.29" />
  <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
  <PackageReference Include="sqlite-net-pcl" Version="1.4.118" />
  <PackageReference Include="SQLitePCLRaw.bundle_green" Version="1.1.9" />
  <PackageReference Include="SQLitePCLRaw.core" Version="1.1.9" />
  <PackageReference Include="Xam.Plugin.Connectivity" Version="3.0.3" />
  <PackageReference Include="Xamarin.Forms" Version="2.5.0.122203" />
  <PackageReference Include="HockeySDK.Xamarin" Version="5.1.2" />
  <PackageReference Include="Plugin.Permissions" Version="2.2.1" />
  <PackageReference Include="Xam.Plugin.Geolocator" Version="4.2.0" />
  <PackageReference Include="Xamarin.Forms.Maps" Version="2.5.0.122203" />
 </ItemGroup>

 

Compatibilidad con paquetes NuGet

Puede darse el caso de que algunos paquetes NuGet no se hayan migrado aún a .NET Standard, pero esto no debería ser problema para migrar nuestro proyecto. Si el paquete no se ha migrado al tratar de restaurar los paquetes obtendremos un error como este:

Package XamarinDiplomado.Participants 1.1.0 is not compatible with netstandard1.0 (.NETStandard,Version=v1.0). Package XamarinDiplomado.Participants 1.1.0 supports: portable-net45+win8+wpa81 (.NETPortable,Version=v0.0,Profile=Profile111)

La forma de solucionarlo es muy simple, debes agregar la etiqueta “AssetTargetFallback” (Antes llamada PackageTargetFallback) dentro del archivo csproj después de la etiqueta donde indicamos la versión de .NET Standard, dentro de esta etiqueta podemos agregar los TargetFramework que necesitemos que sean compatibles.

Para mas información esta la documentación  aunque básicamente el funcionamiento es que si el paquete no encuentra un ensamblado compatible con la versión de .NET Standard de nuestro proyecto, entonces buscará uno compatible basandose en los profile definidos en la etiqueta AssetTargetFallback.

Para nuestro caso quedaría así tras el cambio, tomando en cuenta que el error nos indica el profile que soporta 111 y las plataformas que lo conforman “portable-net45+win8+wpa81”.

NOTA: Cada NuGet restaurado con este método marcará un warning el cúal se puede quitar usando esta documentación. Recuerda que AssetTargetFallback te permite usar NuGets que estes seguro que son compatibles con las plataformas en las que usaras tu librería. En el caso de Xamarin deberías usar un Target Framework Moniker que soporte Xamarin por ejemplos los de los profile 111 (portable-net45+win8+wpa81) o 259 (portable-net45+win8+wpa81+wp8) que son los Profile mas comunes.

<PropertyGroup>
   <TargetFramework>netstandard1.0</TargetFramework>
   <AssetTargetFallback>portable-net45+win8+wpa81</AssetTargetFallback>
 </PropertyGroup>

En caso de encontrar mas errores podemos agregar mas TargetFramework y tendríamos una etiqueta parecida a esta

<PropertyGroup>
   <TargetFramework>netstandard1.0</TargetFramework>
   <<AssetTargetFallback>portable-net45+win8+wp8+wpa81;portable-win+net45+wp80+win81+wpa81;portable-net45+win8+wpa81</AssetTargetFallback>
 </PropertyGroup>

Después de realizar estos pasos hay que eliminar el archivo packages.config y el proyecto debe compilar sin ningún problema.

 

Consideraciones extra

El nuevo proyecto de .NET Standard genera de forma automática el archivo «AssemblyInfo.cs» si en tu proyecto PCL tenías uno dentro de la carpeta «Properties» probablemente obtengas una serie de errores como el siguiente:

Project.AssemblyInfo.cs(12,12): Error CS0579: Duplicate ‘System.Reflection.AssemblyCompanyAttribute’ attribute (CS0579) (DemoAzureOfflineSync)

Para resolverlo hay dos opciones, si quieres mantener tu archivo «AssemblyInfo.cs» puedes agregar la siguiente etiqueta al archivo .csproj de tu proyecto PCL

  <GenerateAssemblyInfo>false</GenerateAssemblyInfo>

La otra opción es poner los datos del «AssemblyInfo.cs» dentro del mismo archivo .csproj y eliminar el archivo AssemblyInfo.cs, por ejemplo:

<PropertyGroup>
       <Version>5.3.0</Version>
       <Authors>Humberto</Authors>
       <Copyright>(c) Humberto Jaimes</Copyright>
</PropertyGroup>

Humberto Jaimes
Humberto Jaimes

Me gusta ayudar a quienes están comenzando con el desarrollo móvil con Xamarin dando sesiones en línea, presenciales en universidades y también ayudo a las compañías que quieren capacitar a su equipo o en la creación de proyectos.

Leave a Reply

Your email address will not be published.