RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 880129
Accepted
Andrey K.
Andrey K.
Asked:2020-09-11 23:21:55 +0000 UTC2020-09-11 23:21:55 +0000 UTC 2020-09-11 23:21:55 +0000 UTC

如何高效地为 .Net Core、Framework、Standard 创建兼容性垫片(shims)

  • 772

如何有效地为.Net Core, Framework,创建兼容性垫片Standard?

版本: Framework 4.6.1 ; Core 2.0; Standard 2.0.

例如,以下 3 件事很有趣,可以在.net core和.net standard之间使用.net framework:

System.Windows.Threading.Dispatcher……System.ComponentModel.ItemPropertyInfo.Descriptor甚至 System.Windows.Controls.MenuItem……

事实上,看起来需要更多这些外壳。当然,它们可以手动创建。但也许有一种更有效的方法来避免机械工作?


如果手动完成,则以粗略的示例说明任务:

例如,Core 2.0没有为Dispatcher.

制作了一个抽象包装器/接口/外观,:

public enum DispatcherShimPriority
{
    Background
    //...
}

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

这里有2个实现:

public class DispatcherCore: DispaicherShim;
//здесь по началу можно просто вызывать Action

和

public class DispatcherFramework: DispaicherShim;
//здесь используется реальный Dispatcher внутри

接下来,制作了某种多用途的激活器类,例如,Shims其中:

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

因此,获得了可用于框架和核心应用程序的外壳。

创建这样的外壳需要大量的机械工作。直觉上,在我看来,没有必要做这项工作,有现成的解决方案......


了解Microsoft.Windows.Compatibility包。我的意思是为该包未涵盖的元素创建包装器。

我听说过Microsoft.Windows.Compatibility.Shims,但我怀疑对于包本身未涵盖的元素没有包装器。


总体目标是将 WPF 应用程序的主体转换为潜在 Web 客户端的核心(留下工作的 WPF),尽管主体的 .net 框架的许多元素并未转换为核心。

c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Andrey K.
    2020-09-20T17:30:19Z2020-09-20T17:30:19Z

    至此,我至少找到了令人满意的方法来创建兼容性垫片。也许有更有效的方法。

    谢谢来自捷克共和国的Firda 。这是他的回答

    1)原则上,一个简单的通用shell就足够了

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

    1.a) Visual Studio片段

    驱动器

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

    shimprop - 类似,尚未完成

    1.b) 分数说明NETCORE和NETFULL

    sdk 样式的.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>
    

    2) 允许遗传的更高级版本

    public interface IShimOne
    {
        void MethodOne();
    }
    public interface IShimTwo: IShimOne
    {
        void MethodTwo();
    }
    
    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) 对象

    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 有更广泛的用途——它们本身已经是包装器)

    //Не до конца сделано, просто чтобы показать идею:
    
    #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
            { }
        }
    }
    
    • 7

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5