Skip to content

Commit 16d4143

Browse files
author
Nikolay Pianikov
committed
#146 Pure.DI.MS isn't Native AOT-friendly
1 parent fdad113 commit 16d4143

5 files changed

Lines changed: 39 additions & 10 deletions

File tree

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
// ReSharper disable NotAccessedPositionalProperty.Global
1+
// ReSharper disable NotAccessedPositionalProperty.Global
2+
using System.Text.Json.Serialization;
3+
24
namespace MinimalWebAPI;
35

4-
public record ClockResult(string Title, string Date, string Time);
6+
public record ClockResult(string Title, string Date, string Time);
7+
8+
[JsonSerializable(typeof(ClockResult))]
9+
partial class AppJsonSerializerContext : JsonSerializerContext;

samples/MinimalWebAPI/MinimalWebAPI.csproj

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22

33
<PropertyGroup>
44
<TargetFramework>$(targetFrameworkVersion)</TargetFramework>
5+
<PublishAot>true</PublishAot>
6+
<PublishTrimmed>true</PublishTrimmed>
7+
<TrimMode>full</TrimMode>
8+
<TrimmerSingleWarn>false</TrimmerSingleWarn>
9+
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
510
</PropertyGroup>
611

712
<ItemGroup>
8-
<ProjectReference Include="..\..\src\Pure.DI.Core\Pure.DI.Core.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
9-
<ProjectReference Include="..\..\src\Pure.DI\Pure.DI.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
10-
<ProjectReference Include="..\Clock\Clock.csproj"/>
13+
<ProjectReference Include="..\..\src\Pure.DI.Core\Pure.DI.Core.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" GlobalPropertiesToRemove="PublishAot;PublishTrimmed;TrimMode;TrimmerSingleWarn;SuppressTrimAnalysisWarnings"/>
14+
<ProjectReference Include="..\..\src\Pure.DI\Pure.DI.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" GlobalPropertiesToRemove="PublishAot;PublishTrimmed;TrimMode;TrimmerSingleWarn;SuppressTrimAnalysisWarnings"/>
15+
<ProjectReference Include="..\Clock\Clock.csproj" GlobalPropertiesToRemove="PublishAot;PublishTrimmed;TrimMode;TrimmerSingleWarn;SuppressTrimAnalysisWarnings"/>
1116
<Compile Include="..\..\src\Pure.DI.MS\any\Pure.DI\MS\*.cs" Link=""/>
1217
</ItemGroup>
1318

samples/MinimalWebAPI/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
// Uses Composition as an alternative IServiceProviderFactory
77
builder.Host.UseServiceProviderFactory(composition);
8+
builder.Services.ConfigureHttpJsonOptions(options =>
9+
options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default));
810

911
var app = builder.Build();
1012

src/Pure.DI.MS/any/Pure.DI/MS/ServiceCollectionFactory.g.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,18 @@ namespace Pure.DI.MS
2626
[global::System.CodeDom.Compiler.GeneratedCode("Pure.DI", "")]
2727
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
2828
#endif
29-
public class ServiceCollectionFactory<TComposition>
29+
public class ServiceCollectionFactory<
30+
#if NET5_0_OR_GREATER || NET
31+
[global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors)]
32+
#endif
33+
TComposition>
3034
{
3135
private static readonly Func<TComposition, InstanceResolver, ServiceDescriptor> ServiceDescriptorProvider;
3236
private static readonly Func<TComposition, TComposition> ScopeFactory;
3337

38+
#if NET5_0_OR_GREATER || NET
39+
[global::System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessage("ReflectionAnalysis", "IL2111", Justification = "The reflection lookup is used only to detect the optional keyed ServiceDescriptor constructor when the referenced Microsoft DI assembly provides it.")]
40+
#endif
3441
static ServiceCollectionFactory()
3542
{
3643
var scopeConstructor = typeof(TComposition).GetConstructor(
@@ -64,11 +71,14 @@ from ctor in typeof(ServiceDescriptor).GetConstructors(BindingFlags.Instance | B
6471
var compositionParameter = Expression.Parameter(typeof(TComposition));
6572
var resolverParameter = Expression.Parameter(typeof(InstanceResolver));
6673
var serviceProviderParameter = Expression.Parameter(typeof(IServiceProvider));
74+
var typeField = typeof(InstanceResolver).GetField(nameof(InstanceResolver.Type));
75+
var tagField = typeof(InstanceResolver).GetField(nameof(InstanceResolver.Tag));
76+
var lifetimeField = typeof(InstanceResolver).GetField(nameof(InstanceResolver.Lifetime));
6777
ServiceDescriptorProvider = Expression.Lambda<Func<TComposition, InstanceResolver, ServiceDescriptor>>(
6878
Expression.New(
6979
ctorWithTag,
70-
Expression.Field(resolverParameter, nameof(InstanceResolver.Type)),
71-
Expression.Field(resolverParameter, nameof(InstanceResolver.Tag)),
80+
Expression.Field(resolverParameter, typeField),
81+
Expression.Field(resolverParameter, tagField),
7282
Expression.Lambda(
7383
resolverType,
7484
Expression.Call(
@@ -78,7 +88,7 @@ from ctor in typeof(ServiceDescriptor).GetConstructors(BindingFlags.Instance | B
7888
serviceProviderParameter),
7989
serviceProviderParameter,
8090
Expression.Parameter(typeof(object))),
81-
Expression.Field(resolverParameter, nameof(InstanceResolver.Lifetime))),
91+
Expression.Field(resolverParameter, lifetimeField)),
8292
compositionParameter,
8393
resolverParameter)
8494
.Compile();

src/Pure.DI.MS/any/Pure.DI/MS/ServiceProviderFactory.g.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,16 @@ namespace Pure.DI.MS
3535
[global::System.CodeDom.Compiler.GeneratedCode("Pure.DI", "")]
3636
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
3737
#endif
38-
public class ServiceProviderFactory<TComposition>: IServiceProviderFactory<IServiceCollection>
38+
public class ServiceProviderFactory<
39+
#if NET5_0_OR_GREATER || NET
40+
[global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors | global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors)]
41+
#endif
42+
TComposition>: IServiceProviderFactory<IServiceCollection>
3943
where TComposition: ServiceProviderFactory<TComposition>
4044
{
45+
#if NET5_0_OR_GREATER || NET
46+
[global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)]
47+
#endif
4148
private static readonly Type KeyedServiceProviderType = Type.GetType("Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider, Microsoft.Extensions.DependencyInjection.Abstractions, Culture=neutral, PublicKeyToken=adb9793829ddae60", false);
4249
private static readonly MethodInfo GetKeyedServiceMethod = KeyedServiceProviderType?.GetMethod("GetKeyedService");
4350
private static readonly ParameterExpression TypeParameter = Expression.Parameter(typeof(Type));

0 commit comments

Comments
 (0)