c# - разница - change target framework to.net core




Как создать или использовать готовые Shims для переноса с.net framework на.net core/standard? (2)

Как создать или использовать готовые Shims для элементов .net framework 4.6.1 для их портирования (из .net framework 4.6.1 ) в .net core 2.0 / .net standard 2.0 ?

Интересующие классы: было бы неплохо иметь прокладки для таких классов, как:

System.Windows.Threading.Dispatcher

или же

System.ComponentModel.ItemPropertyInfo.Descriptor

четное

System.Windows.Controls.MenuItem

и многое другое ...

Контекст:

Приложение (код) не на 100% хорошо организовано. Бизнес-логика не отделена на 100% от логики пользовательского интерфейса. Ответ «сначала сделай рефакторинг», безусловно, хороший ответ. Но в моем случае все не на 100% так, как должно быть в идеале.

Примерный пример, попробуйте сделать это вручную:

System.Windows.Threading.Dispatcher не реализован в Core 2.0 .

Можно попытаться добавить:

public enum DispatcherShimPriority
{
    Background
    //...
}

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

Далее следуют две реализации этого интерфейса:

public class DispatcherCore: DispaicherShim;

а также

public class DispatcherFramework: DispaicherShim;

Далее следует класс (назовем его Shims ) в многоцелевом проекте:

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

Результатом является прокладка, которая может использоваться в разных API.

Это правильный подход?

На самом деле, создание таких прокладок требует много рутинной работы. У меня такое ощущение, что эту работу не нужно выполнять. У меня такое ощущение, что есть готовое решение этой проблемы ...

Я знаю о пакете Microsoft.Windows.Compatibility . Вопрос скорее связан с портированием, когда WPF связан со многими элементами, специфичными для wpf. Эти элементы отсутствуют в пакете Microsoft.Windows.Compatibility , но, к сожалению, они используются во всех моих сборках, которые являются кандидатами для перенаправления на .Net Core 2.0 . Я имею в виду шимминг тех классов, которых нет в Microsoft.Windows.Compatibility .

Хорошо, у нас есть Microsoft.Windows.Compatibility.Shims , но я не уверен, что это полезно в моем случае; особенно после прочтения следующего текста :

Microsoft.Windows.Compatibility.Shims : этот пакет предоставляет инфраструктурные сервисы, и на него нельзя ссылаться непосредственно из вашего кода ....

Upd: подчеркивая, что конечной целью является .net core 2.0

Upd2: вся задача - перенести основную часть приложения WPF на .net core (оставив работающее приложение WPF ) для потенциального веб-клиента . Основная часть содержит элементы .net framework которые не реализованы для .net core .

Upd3: пара слов о полной стратегии: более полная стратегия - это общие проекты, первый подход в этой статье (#if) . В моей стратегии есть два основных шага: один - постепенно портировать код, начиная с базовых библиотек и заканчивая топовыми библиотеками, но с интенсивным использованием заглушек и исключений PlatformNotSupportedException . Вторым шагом является переход от верхних библиотек к базовым библиотекам, заменяющим заглушки и исключения реализациями ядра .net, по требованию (!) - нет необходимости заменять все заглушки и исключения.

Upd4 Мы уже разделили переносимые тесты из непереносимых тестов (на две библиотеки). Очень важно, чтобы мы запускали тесты во время процесса портирования.


Ниже приведены, по крайней мере, удовлетворительные подходы:

Спасибо Firda из Чехии. Это его ответ

1) мне достаточно общего шимма (фрагменты могут помочь)

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

ПРИМЕР:

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
    { }
}

Мой файл .csproj стиле .csproj чтобы прояснить NETFULL и 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) Фрагменты 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
        }

шимпроп - пока нет

2) Случай, когда необходимо наследование.

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.а) Объекты для наследования

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) Готовые «аналоги» для элементов управления GUI ( Eto.Forms )

(на самом деле Eto.Forms имеет более широкое применение - они прокладки)

Эту среду можно использовать для создания приложений, работающих на нескольких платформах, с использованием их собственного набора инструментов с простым в использовании API. Это заставит ваши приложения выглядеть и работать как родное приложение на всех платформах, используя одну кодовую базу пользовательского интерфейса ...

//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
        { }
    }
}

Переход от Standard .Net к .Net Core - это не просто обновление, его можно назвать переходом на новую платформу с учетом того, как все складывается. Переход на ядро ​​.Net означает изучение и создание новой инфраструктуры, в которую можно скопировать существующий код.

Из-за больших различий между .Net core 1, 1.1, 2.0 и 2.1 форма процесса миграции сильно изменилась, поэтому не существует одного размера, подходящего для всех "прокладок", и было бы быстро создать какую-либо оболочку или инструмент миграции. устарели. Необходимо выполнить работу для переноса вашего кода.

Некоторые основные API-интерфейсы ОС похожи, но большая часть кода платформы была перемещена или изменена, поэтому поиск подобной замены также может быть затруднен. На самом деле стоит провести некоторые исследования и разработки, чтобы увидеть, в чем различия, не говоря уже об использовании сторонних библиотек и т. Д.





shim