使用本地定义的类,而不是库/包提供的类 C# IL Weaving

Using a locally defined class instead of the one provided by a library/package C# IL Weaving

提问人:Amir Hajiha 提问时间:3/22/2022 更新时间:3/22/2022 访问量:107

问:

我见过像 Fody 这样的东西,实际上一直在使用 PropertyChanged,它在实现 INotifyPropertyChanged 接口后减少了样板代码。

我相信这是通过“编织 IL”来完成的,所以我想到了一个想法。

问题是我正在尝试定义我自己的类版本并使用它而不是 nuget 包中定义的版本。这是因为库处理 TextView,而我希望它处理 AppCompatTextView。

AppCompatTextView 是:

public class AppCompatTextView : 
    TextView,
    IEmojiCompatConfigurationView,
    IJavaObject,
    IDisposable,
    IJavaPeerable,
    ITintableBackgroundView,
    IAutoSizeableTextView,
    ITintableCompoundDrawablesView

如您所见,AppCompatTextView 继承自 TextView,这应该会让事情变得更容易。

默认情况下,库 (Xamarin.Forms) 已将 LabelRenderer 定义为:

public class LabelRenderer : FormsTextView, IVisualElementRenderer, IViewRenderer, ITabStop

哪里:

namespace Xamarin.Forms.Platform.Android
{
    public class FormsTextView : TextView
    {
        public FormsTextView(Context context) : base(context)
        {
        }

        [Obsolete]
        public FormsTextView(Context context, IAttributeSet attrs) : base(context, attrs)
        {
        }

        [Obsolete]
        public FormsTextView(Context context, IAttributeSet attrs, int defStyle) : base(context, attrs, defStyle)
        {
        }

        [Obsolete]
        protected FormsTextView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
        {
        }

        [Obsolete]
        public void SkipNextInvalidate()
        {
        }
    }
}

但是,我想创建自己的 LabelRenderer 版本,该版本继承自 AppCompatTextView。

这是为了满足 Google 概述的显示现代表情符号的要求

查看 Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer 的代码时,我们可以看到:

protected global::Android.Widget.TextView Control => this;

我想到的想法是,是否可以使用一些 IL Weaving 工具,以便它是这样的:

protected global::AndroidX.AppCompat.Widget.AppCompatTextView Control => this;

换句话说,当它想要加载此 IL 时,是否有可能以一种方式“编织 IL”:

  .property instance class [Mono.Android]Android.Widget.TextView Control()
  {
    .get instance class [Mono.Android]Android.Widget.TextView Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer::get_Control()
  } 

它应该是 AndroidX.AppCompat.Widget.AppCompatTextView 而不是 Android.Widget.TextView:

.property instance class [Mono.Android]AndroidX.AppCompat.Widget.AppCompatTextView Control()
  {
    .get instance class [Mono.Android]AndroidX.AppCompat.Widget.AppCompatTextView Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer::get_Control()
  } // end of property LabelRenderer::Control

谢谢!

C# Xamarin.Android Fody 中间语言

评论

0赞 Robert Harvey 3/22/2022
是的,这是可能的。它是否实用或可取是另一回事。
1赞 canton7 3/22/2022
从表面上看,我不明白为什么不。在这个过程中,它是否会破坏其他任何东西,我不能说。你可能想要一些可以作为命令行应用运行的东西,而不是作为 MSBuild 任务运行的东西。我已经快速浏览了 Fody 文档,但找不到任何相关内容。直接使用 Mono.Cecil 可能更容易:这是 Fody 在后台使用的库。

答: 暂无答案