dotnet / dotnet/linker

Blazor linker strips away a method in a generated class even if the settings indicate not to.

Open
#2,358 21 comments 0 reactions 0 assignees View on GitHub
area-Linker: Diagnostic
Dominant language
C#
Stars
392
Forks
128
Avg merge
2d 10h
Merged PRs (30d)
2

Description

Environment:
* Windows 10 Enterprise
* Version 10.0.19043 Build 19043
* Visual Studio 2022 Current
* .NET 6.0

Steps to reproduce the issue:
* clone the repository at https://github.com/kephas-software/kephas (master)
* open the src/Kephas.sln solution and build it.
* start the Blazor app in Tests/Kephas.AspNetCore.Blazor.InteractiveTests/Kephas.AspNetCore.Blazor.InteractiveTests.Server
* the application crashes while bootstrapping, the stack trace is visible in the browser console (see the attachment).
![BlazorTrimmer error](https://user-images.githubusercontent.com/3511581/140806035-425bf3b0-0a30-4868-9cfa-1ef00918feb4.png)

Due to the fact that it happens during bootstrap I cannot debug properly, but I managed to trace down to the code causing the issue:
\src\Kephas.Injection\Services\AppServicesAttribute.cs, line 131.
When the returned instance is returned to the caller, either the ToArray() extension method or the SelectMany() crashes.

Background:
* the AppServicesAttribute is used to collect services for the dependency injection through a provider class, provided in the constructor and implementing the IAppServiceInfosProvider interface.
* This attribute implements itself the IAppServiceInfosProvider interface, redirecting the interface methods to the instance created upon request.
* The provider type is annotated with ```[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]``` in the AppServicesAttribute's constructor.
* The provider classes are generated by an analyzer, one per assembly. The generated class where the issue occurs is listed below (can be found, after compilation, in src/Kephas.Application/obj/.generated/Kephas.Analyzers/Kephas.Analyzers.Injection.AppServicesSourceGenerator/AppServices.g.cs

``` C#
#nullable enable

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

using Kephas.Services;

[assembly: AppServices(typeof(Kephas.Injection.Generated.AppServices_Kephas_Application))]

namespace Kephas.Injection.Generated
{
#if NET6_0_OR_GREATER
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
#endif
internal partial class AppServices_Kephas_Application: IAppServiceInfosProvider
{
IEnumerable? IAppServiceInfosProvider.GetContractDeclarationTypes(IContext? context)
{
yield return typeof(Kephas.Application.IAppMainLoop);
yield return typeof(Kephas.Application.IAppManager);
yield return typeof(Kephas.Application.IFeatureLifecycleBehavior);
yield return typeof(Kephas.Application.IFeatureManager);
}

IEnumerable IAppServiceInfosProvider.GetAppServices(IContext? context)
{
yield return new ServiceDeclaration(typeof(Kephas.Application.CommandsAppSetupHandler), typeof(Kephas.Application.IAppSetupHandler));
yield return new ServiceDeclaration(typeof(Kephas.Application.DefaultAppMainLoop), typeof(Kephas.Application.IAppMainLoop));
yield return new ServiceDeclaration(typeof(Kephas.Application.DefaultAppManager), typeof(Kephas.Application.IAppManager));
yield return new ServiceDeclaration(typeof(Kephas.Application.FeatureEnabledServiceBehavior), typeof(Kephas.Services.Behaviors.IEnabledServiceBehaviorRule<, >));
yield return new ServiceDeclaration(typeof(Kephas.Application.Interaction.InteractionFeatureLifecycleBehavior), typeof(Kephas.Application.IFeatureLifecycleBehavior));
yield return new ServiceDeclaration(typeof(Kephas.Application.MainLoopAppLifecycleBehavior), typeof(Kephas.Application.IAppLifecycleBehavior));
yield return new ServiceDeclaration(typeof(Kephas.Application.SetupAppLifecycleBehavior), typeof(Kephas.Application.IAppLifecycleBehavior));
yield return new ServiceDeclaration(typeof(Kephas.Application.StartupAppLifecycleBehavior), typeof(Kephas.Application.IAppLifecycleBehavior));
}
}
}

```

From intermediary steps, which I cannot reproduce anymore, I am quite certain that the method ```IAppServiceInfosProvider.GetAppServices``` is called for ```AppServices_Kephas_Application```. However, presumably, the object returned is missing some methods leading to the error in ```class-setup-vtable.c```. I tried to indicate at all steps that the assemblies should not be trimmed, due to heavy use of reflection, but to no avail.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.