Problem Discovery#
Recently, while developing an Avalonia application, I found that it ran normally during debugging but could not run after publishing, which felt strange. My publish configuration included the following two lines:
<PublishTrimmed>True</PublishTrimmed>
<PublishAot Condition="'$(Configuration)' != 'Debug'">true</PublishAot>
The first line enabled trimming, and the second line enabled AOT compilation (but it was not enabled during development because the preview window does not support AOT).
After some investigation, I discovered that both had issues:
- Reflection is not friendly to AOT; my
ViewLocator.cs
used reflection to create objects. - Some libraries do not support trimming well, so trimming needs to be disabled for them.
Solution#
Issue 1: Eliminate Reflection#
The original code used reflection to create objects:
public Control? Build(object? param)
{
if (param != null && param is ViewModelBase)
{
var viewModelType = param.GetType();
if (_viewModelViewMappings.TryGetValue(viewModelType, out var viewType))
{
return (Control)Activator.CreateInstance(viewType)!; // Reflection used here
}
return new TextBlock { Text = "Not Found: " + viewModelType.FullName };
}
return null;
}
After modification, it used a factory method:
public Control? Build(object? param)
{
if (param != null && param is ViewModelBase)
{
var viewModelType = param.GetType();
if (_viewModelViewMappings.TryGetValue(viewModelType, out var viewFactory))
{
return viewFactory(); // Factory method used
}
return new TextBlock { Text = "Not Found: " + viewModelType.FullName };
}
return null;
}
This eliminates the use of reflection.
Issue 2: Disable Trimming for Specific Libraries#
During publishing, I noticed many trimming warnings like these:
2>Assembly 'Serilog' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries
2>Assembly 'ReactiveUI' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries
2>Assembly 'SukiUI' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries
2>Assembly 'Avalonia.Controls.DataGrid' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries
2>Assembly 'Avalonia.Controls.DataGrid' produced AOT analysis warnings.
Therefore, I modified the project's sln file to add the following snippet, using an external XML file to limit trimming:
<ItemGroup>
<TrimmerRootDescriptor Include="TrimmerRoots.xml" />
</ItemGroup>
Below is the content of TrimmerRoots.xml
:
<?xml version="1.0" encoding="utf-8" ?>
<linker>
<assembly fullname="Serilog" />
<assembly fullname="Serilog.Sinks.Console" />
<assembly fullname="Serilog.Sinks.File" />
<assembly fullname="ReactiveUI" />
<assembly fullname="SukiUI" />
<assembly fullname="Serilog.Sinks.File" />
</linker>
I included all the projects that had warnings, and although there were still new warnings during subsequent compilations, the application could run normally. Thus, all issues were resolved.