unoplatform / uno

Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
https://platform.uno
Apache License 2.0
8.8k stars 707 forks source link

Reflection & WASM, assembly got linked. #145

Closed CobraCalle closed 6 years ago

CobraCalle commented 6 years ago

I have a class like this…

[Operation("+", 20)]
public class Add : Operation
{
    internal Add(Formula formula, Value left, Value right)
        : base(formula, left, right)
    {
    }

}

Now I what to create this type by reflection and try to get the constructor…

                System.Reflection.ConstructorInfo constructor = operation.GetConstructor(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic, null, new Type[] { typeof(Diomex.Framework.Math.FormulaParser.Formula), typeof(Diomex.Framework.Math.FormulaParser.Value), typeof(Diomex.Framework.Math.FormulaParser.Value) }, null);

"operation" is here typeof(Add)

This works well… except in the WASM-version… there is constructor null

Any ideas?

carldebilly commented 6 years ago

That's because your assembly got linked during compilation. This means the linker considers this constructor is never called and get rid of it.

You can hint the linker like we did in the playground:

  1. Create a file called LinkerConfig.xml like this: https://github.com/nventive/Uno.Playground/blob/master/src/Uno.Playground.WASM/LinkerConfig.xml and add relevant assemblies/namespaces/types. You can find the documentation here: https://github.com/mono/linker/tree/master/linker#syntax-of-xml-descriptor
  2. Reference your file in the .csproj like this: https://github.com/nventive/Uno.Playground/blob/master/src/Uno.Playground.WASM/Uno.Playground.WASM.csproj#L43

Another way to do that would be to add a [Preserve] attribute on your class. https://github.com/nventive/Uno/blob/master/src/Uno.Foundation/PreserveAttribute.cs