You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The MAUI Community Toolkit provides guidance on creating "slim bindings" called "Native Method Interop". There are a few downsides to this approach:
It requires non-trivial Java knowledge to set up Android Studio, a Java Binding project, and write a Java wrapper API.
Integrating the wrapped .jar and potentially its dependencies into the managed app can be tricky, getting its versions to align with .jar files pulled in through NuGet packages.
Once we're already down the path of asking users to write the APIs by hand, could we use Roslyn source generators to allow them to do the same in C#?
Note
A very quick prototype and sample is available here.
Example
Using the example from MAUI Community Toolkit, we could allow the user to write the C# API that matches the Java API to bind:
// Java API to bindpackagecom.facebook;
publicclassFacebookSdk {
publicfinalvoidsetIsDebugEnabled (Booleanvalue) { ... }
}
// C# user writes[JavaBindingType("com.facebook.FacebookSdk")]publicpartialclassFacebookSdk:Java.Lang.Object{[JavaBindingMethod("setIsDebugEnabled")]publicpartialvoidSetIsDebugEnabled(boolvalue);}
We could then use a Roslyn source generator to fill in the plumbing in a generated partial class:
// Additional C# that gets generated[global::Android.Runtime.Register("com/facebook/FacebookSdk",DoNotGenerateAcw=true)]publicpartialclassFacebookSdk{[Register("setIsDebugEnabled","(Z)V","")]publicpartialunsafevoidSetIsDebugEnabled(boolvalue){conststring__id="setIsDebugEnabled.(Z)V";try{JniArgumentValue*__args=stackallocJniArgumentValue[1];__args[0]=newJniArgumentValue(nonRoot);_members.InstanceMethods.InvokeVirtualVoidMethod(__id,this,__args);}finally{}}}
Vague Typing
This proposal could also incorporate the principles of Vaguely Typed Slim Bindings, allowing the user to bind as much or as little as they want.
These bindings should compose well with existing bound libraries. Imagine a MapActivity that subclasses androidx.activity.Activity. Adding the Xamarin.AndroidX.Activity NuGet package would allow your bound type to easily subclass the "real" class:
The largest downside is likely the lack of compile-time checking. If a user misspells a Java type or method name, we won't have tooling that can verify it, so they will receive a runtime error. Same if the user provides incorrect parameter or return types, or provides the wrong number of parameters.
Background
The MAUI Community Toolkit provides guidance on creating "slim bindings" called "Native Method Interop". There are a few downsides to this approach:
.jarand potentially its dependencies into the managed app can be tricky, getting its versions to align with.jarfiles pulled in through NuGet packages.Once we're already down the path of asking users to write the APIs by hand, could we use Roslyn source generators to allow them to do the same in C#?
Note
A very quick prototype and sample is available here.
Example
Using the example from MAUI Community Toolkit, we could allow the user to write the C# API that matches the Java API to bind:
We could then use a Roslyn source generator to fill in the plumbing in a generated partial class:
Vague Typing
This proposal could also incorporate the principles of Vaguely Typed Slim Bindings, allowing the user to bind as much or as little as they want.
Imagine the Java API:
If the user just wants to add the map pin and isn't interested in using the return value, they can bind it as
Java.Lang.Object:If they want to interact with the
MapPintype, they can provide as much of it as they want:Interaction with Existing Bindings
These bindings should compose well with existing bound libraries. Imagine a
MapActivitythat subclassesandroidx.activity.Activity. Adding theXamarin.AndroidX.ActivityNuGet package would allow your bound type to easily subclass the "real" class:Downsides
The largest downside is likely the lack of compile-time checking. If a user misspells a Java type or method name, we won't have tooling that can verify it, so they will receive a runtime error. Same if the user provides incorrect parameter or return types, or provides the wrong number of parameters.