Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建或使用现成的垫片从.net framework移植到.net core/standard?_C#_.net_.net Core_Porting_Shim - Fatal编程技术网

C# 如何创建或使用现成的垫片从.net framework移植到.net core/standard?

C# 如何创建或使用现成的垫片从.net framework移植到.net core/standard?,c#,.net,.net-core,porting,shim,C#,.net,.net Core,Porting,Shim,如何为.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 还有更多

如何为
.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%组织良好。业务逻辑与UI逻辑并非100%分离。答案“首先进行重构”绝对是一个好答案。但在我的情况下,事情并不是100%的理想状态


近似示例,一个尝试按常规操作的示例:

System.Windows.Threading.Dispatcher
未在核心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;

在多目标项目中,后跟一个a类(我们称之为
a
):

public static DispaicherShim CreateDispatcher()
{
#if NETCOREAPP2_0
    return new DispatcherCore();
#else
    return new DispatcherFramework();
#endif       
}
结果就是垫片,可以在不同的API中使用

这是正确的方法吗?


实际上,制作这样的垫片需要很多日常工作。我觉得这项工作没有必要进行。我觉得这个问题有现成的解决办法


我知道
Microsoft.Windows.Compatibility
package。当
WPF
涉及许多特定于WPF的元素时,问题与移植相关。这些元素不在Microsoft.Windows.Compatibility包中,但不幸的是,它们在我的程序集中使用,这些程序集是重定目标到
.Net Core 2.0
的候选程序集。我的意思是填充那些不在
Microsoft.Windows.Compatibility
中的类

好的,我们有这个
Microsoft.Windows.Compatibility.垫片
,但我不确定它对我的情况是否有用;特别是在阅读了以下内容后:

Microsoft.Windows.Compatibility.垫片:此软件包提供 基础设施服务,不应直接从 你的代码


Upd:强调最终目标是
.net core 2.0

Upd2:整个任务是将WPF应用程序的主要部分移植到
.net core
(离开工作的WPF应用程序)以供潜在的web客户端使用。主要部分包含
.net framework
元素,这些元素不是为
.net core
实现的

Upd3:关于完整战略的两个词:越完整的战略是共享项目。在我的策略中有两个主要步骤:一个是逐渐移植代码,从基本库开始,在顶级库结束,但大量使用存根和
PlatformNotSupportedException
s。第二步是从顶级库转移到基本库,通过.net核心实现按需替换存根和异常(!)-无需替换所有存根和异常


Upd4我们已经将可移植测试与非可移植测试分开(分成两个LIB)。在移植过程中运行测试非常重要。

以下是至少令人满意的方法:

捷克共和国的感谢

1) 通用垫片对我来说已经足够了(代码片段可能会有所帮助) 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
        { }
  }
}
shimprop-还没有


2) 需要继承时的情况。 2.a)继承对象
3) 准备好GUI控件的“对应项”() (实际上,Eto.Forms的应用范围更广——它们是填隙片)

此框架可用于构建应用程序,这些应用程序使用其本机工具包和易于使用的API跨多个平台运行。这将使您的应用程序在所有平台上都像本机应用程序一样,使用单个UI代码库

//没有完全实现,只是展示了想法:
#如果未满
使用System.Windows.Controls;
#艾利夫网芯
使用Eto.Forms;
#恩迪夫
命名空间可移植性库
{
公共类菜单项填隙:填隙<
#如果未满
梅努伊特姆
#艾利夫网芯
梅努伊特姆
#恩迪夫
>
{
公共菜单项(EventHandler dlg)
#如果未满
:base(新菜单项(/*未实现*/))
#艾利夫网芯
:基础(新按钮菜单项(dlg))
#恩迪夫
{ }
}
}

从标准.Net移动到.Net核心不仅仅是一种升级,考虑到事物的组合方式,您几乎可以称之为移动到新平台。迁移到.NETCore意味着学习并创建一个可以复制现有代码的新框架

由于.Net core 1、1.1、2.0和2.1之间的巨大差异,这些版本的迁移过程发生了很大的变化,因此不存在“一刀切”的“垫片”,使用某种包装器或迁移工具很快就会过时。迁移代码需要做一些工作


一些核心操作系统API是类似的,但是很多框架代码已经被移动或更改,所以寻找类似的交换可能也很困难。做一些研究和开发工作确实值得,看看其中的差异在哪里,更不用说第三方库的使用等了。

这是一个非常有趣的问题,但我不确定这里是否有灵丹妙药。我以前转换过应用程序,一种循序渐进的方法似乎效果最好,使用现有代码并慢慢地对其进行重新分解和升级,.NET核心库可以被.NET framework项目引用()-作为维护和部署的常规策略的一部分,我会逐渐将逻辑移到新的库文件中。在我看来,在缺乏更完整的战略的情况下,填隙片听起来有点像是在转移注意力
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
    { }
}
<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>
#if NETFULL

#elif NETCORE

#endif
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
        { }
  }
}
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
        {}
  }
}
        public void $methodname$()
        {
#if NETFULL
        It.$methodname$();
#elif NETCORE
        It.$methodname$();
        //throw new ShimException();
#endif
        }
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(); }
}
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(); }
//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
        { }
    }
}