standard net from framework convert clases biblioteca c# .net .net-core porting shim

c# - from - ¿Cómo crear o usar Shims listos para portar de.net framework a.net core/standard?



convert.net framework to.net core (2)

Los siguientes son al menos enfoques satisfactorios:

Gracias Firda de República Checa. Esta es su respuesta

1) El suplemento genérico es suficiente para mí (los fragmentos pueden ayudar)

public abstract class Shim<TImpl> { internal TImpl It { get; } protected Shim(TImpl it) { It = it; } }

EJEMPLO:

public class DispatcherPriorityShim : Shim< #if NETFULL DispatcherPriority #elif NETCORE string #endif > { public DispatcherPriorityShim(string it) #if NETFULL : base((DispatcherPriority)Enum.Parse(typeof(DispatcherPriority), it)) #elif NETCORE : base(it) #endif { } }

Mi archivo .csproj estilo .csproj para aclarar NETFULL y NETCORE :

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup><TargetFrameworks>netstandard2.0;netcoreapp2.0;net461</TargetFrameworks></PropertyGroup> <PropertyGroup Condition=" ''$(TargetFramework)'' == ''netcoreapp2.0'' OR ''$(TargetFramework)'' == ''netstandard2.0''"> <DefineConstants>NETCORE;</DefineConstants></PropertyGroup> <PropertyGroup Condition=" ''$(TargetFramework)'' == ''net461''"> <DefineConstants>NETFULL;</DefineConstants></PropertyGroup> </Project>

1.a) snippets Visual Studio

drv

#if NETFULL #elif NETCORE #endif

shimenum

namespace PortabilityLibrary.Shims { public class $enumname$Shim : Shim< #if NETFULL $enumname$ #elif NETCORE string #endif > { public $enumname$Shim(string it) #if NETFULL : base(($enumname$)Enum.Parse(typeof($enumname$), it)) #elif NETCORE : base(it) #endif { } } }

shimsnip

namespace PortabilityLibrary.Shims { public class $classname$Shim : Shim< #if NETFULL $classname$ #elif NETCORE $classname$ //NullObject #endif > { public $classname$Shim() #if NETFULL : base(new $classname$()) #elif NETCORE : base(new $classname$()) //: base(new NullObject()) #endif {} } }

shimmeth

public void $methodname$() { #if NETFULL It.$methodname$(); #elif NETCORE It.$methodname$(); //throw new ShimException(); #endif }

shimprop - todavía no

2) Caso cuando se necesite herencia.

public interface IShimOne { void MethodOne(); } public interface IShimTwo: IShimOne { void MethodTwo(); } #if NETFULL class One: RealOne, IShimOne {} class Two: RealTwo, IShimTwo {} public static class ShimFactory { public static IShimOne CreateOne() { return new One(); } public static IShimTwo CreateTwo() { return new Two(); } }

2.a) Objetos por herencia.

public class WrapperOne { protected IShimOne It { get; } protected WrapperOne(IShimOne it) { It = it; } public WrapperOne() { It = ShimFactory.CreateOne(); } public void MethodOne() { It.MethodOne(); } } public class WrapperTwo: WrapperOne { protected new IShimTwo It => (IShimTwo)base.It; protected WrapperTwo(IShimTwo it): base(it) {} public WrapperTwo(): base(ShimFactory.CreateTwo()) {} public void MethodTwo() { It.MethodTwo(); }

3) Listos "homólogos" para controles GUI ( Eto.Forms )

(en realidad, Eto.Forms tiene una aplicación más amplia, son las cuñas)

Este marco puede usarse para crear aplicaciones que se ejecutan en múltiples plataformas utilizando su kit de herramientas nativo, con una API fácil de usar. Esto hará que sus aplicaciones se vean y funcionen como una aplicación nativa en todas las plataformas, utilizando un solo código base de UI ...

//Not fully implemented, just showing the idea: #if NETFULL using System.Windows.Controls; #elif NETCORE using Eto.Forms; #endif namespace PortabilityLibrary.Shims { public class MenuItemShim : Shim< #if NETFULL MenuItem #elif NETCORE MenuItem #endif > { public MenuItemShim(EventHandler<EventArgs> dlg) #if NETFULL : base(new MenuItem(/*not implemented*/)) #elif NETCORE : base(new ButtonMenuItem(dlg)) #endif { } } }

¿Cómo crear o utilizar elementos Shims listos para .net framework 4.6.1 para trasladarlos (desde .net framework 4.6.1 ) a .net core 2.0 / .net standard 2.0 ?

Algunas clases de interés: sería bueno tener cuñas para clases como:

System.Windows.Threading.Dispatcher

o

System.ComponentModel.ItemPropertyInfo.Descriptor

incluso

System.Windows.Controls.MenuItem

y muchos más...

Contexto:

La aplicación (el código) no está 100% bien organizada. La lógica de negocios no está separada al 100% de la lógica de UI. La respuesta "hacer primero la refactorización" es definitivamente una buena respuesta. Pero en mi caso las cosas no son 100% como deberían ser idealmente.

Ejemplo aproximado, un intento de hacerlo manualmente:

System.Windows.Threading.Dispatcher no está implementado en Core 2.0 .

Uno podría intentar agregar:

public enum DispatcherShimPriority { Background //... } public interface DispaicherShim { void Invoke(Action action, DispatcherShimPriority prio); void BeginInvoke(Action action, DispatcherShimPriority, prio); }

Seguido por dos implementaciones de esta interfaz:

public class DispatcherCore: DispaicherShim;

y

public class DispatcherFramework: DispaicherShim;

Seguido por una clase (llamémosle Shims) en un proyecto de múltiples destinos:

public static DispaicherShim CreateDispatcher() { #if NETCOREAPP2_0 return new DispatcherCore(); #else return new DispatcherFramework(); #endif }

El resultado es el shim, que podría usarse en diferentes API.

¿Es este un enfoque correcto?

En realidad, crear tales calzas requiere mucho trabajo de rutina. Tengo la sensación de que este trabajo no es necesario para ser realizado. Tengo la sensación de que hay una solución lista para este problema ...

Soy consciente de paquete de Microsoft.Windows.Compatibility . La pregunta está más bien relacionada con la migración cuando WPF está involucrada con muchos elementos específicos de wpf. Esos elementos no se encuentran en Microsoft.Windows.Compatibility paquete Microsoft.Windows.Compatibility , pero, desafortunadamente, se usan en mis ensamblajes, que son candidatos para volver a dirigir a .Net Core 2.0 . Me refiero a cambiar esas clases, que no están en Microsoft.Windows.Compatibility .

Ok, tenemos este Microsoft.Windows.Compatibility.Shims , pero no estoy seguro de que sea útil en mi caso; Especialmente después de leer el siguiente texto :

Microsoft.Windows.Compatibility.Shims : este paquete proporciona servicios de infraestructura y no debe ser referenciado directamente desde su código ...

Actualizaciones: enfatizando que el objetivo final es .net core 2.0

Upd2: toda la tarea es trasladar la mayor parte de una aplicación WPF al .net core (dejando la aplicación WPF en funcionamiento) para un posible cliente web . La parte principal contiene elementos del .net framework que no están implementados para el .net core .

Upd3: Un par de palabras acerca de la estrategia completa: la estrategia más completa es Proyectos compartidos, primer enfoque en este artículo (#if) . Hay 2 pasos principales en mi estrategia: uno es el código de puerto de forma gradual, comenzando desde las bibliotecas base y terminando en las bibliotecas principales, pero con un uso intenso de stubs y PlatformNotSupportedException s. El segundo paso es pasar de las bibliotecas principales a las bibliotecas base, sustituyendo los apéndices y las excepciones por implementaciones del núcleo .net, On demand (!): No es necesario subsituir todos los apéndices y excepciones.

Upd4 Ya hemos dividido las pruebas portátiles de las pruebas no portátiles (en dos bibliotecas). Es muy importante que ejecutemos las pruebas durante el proceso de transferencia.


Pasar de Standard .Net a .Net Core no es solo una actualización, casi se podría llamar un cambio a una nueva plataforma teniendo en cuenta cómo se organizan las cosas. Pasar a .Net core significa aprender y crear un nuevo marco donde se pueda copiar el código existente.

Debido a las grandes diferencias entre .Net core 1, 1.1, 2.0 y 2.1 El proceso de migración de estos ha cambiado mucho, por lo que no hay una talla única para todos "shim" y tener algún tipo de envoltorio o herramienta de migración se haría rápidamente obsoleto. Se debe trabajar para migrar su código.

Algunas API básicas del sistema operativo son similares, pero se ha movido o cambiado una gran cantidad de código de marco, por lo que la búsqueda de intercambios similares también puede ser difícil. Realmente vale la pena hacer un poco de I + D para ver dónde están las diferencias por no mencionar el uso de bibliotecas de terceros, etc.