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

114 Views Asked by At

I have seen stuff like Fody and in fact have been using PropertyChanged which reduces the boilerplate code after implementing the INotifyPropertyChanged interface.

I believe it is done by 'weaving the IL' so an idea crossed my mind.

The problem is that I am trying to define my own version of a class and use it instead of the one defined in a nuget package. This is because the library one deals with a TextView whereas I would like it to deal with an AppCompatTextView instead.

AppCompatTextView is:

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

As you can see, AppCompatTextView inherits from TextView and this should make things easier.

By default, the library (Xamarin.Forms) has defined a LabelRenderer as:

public class LabelRenderer : FormsTextView, IVisualElementRenderer, IViewRenderer, ITabStop

Where:

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

However, I would like to create my own version of LabelRenderer which inherits from AppCompatTextView instead.

This is to meet the requirements outlined by Google to display modern emojis

When seeing the code for Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer, we can see that:

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

The idea that came to my mind was that would it be possible to use some IL Weaving tool so that it would be this instead:

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

In other words, would it be possible to 'weave the IL' in a way that when it wants to load this 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()
  } 

It should be an AndroidX.AppCompat.Widget.AppCompatTextView instead of 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

Thanks!

0

There are 0 best solutions below