Skip to content

Commit 7cb7729

Browse files
committed
Added AOT attributes to plugins.
1 parent f1a4a51 commit 7cb7729

13 files changed

+48
-143
lines changed

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins.AspNetCore.Mvc/AppCoreNet.Extensions.Hosting.Plugins.AspNetCore.Mvc.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
55
<Description>Provides MVC plugin extensions to the Microsoft.Extensions.Hosting framework.</Description>
6+
<!-- Without this, ILLink analyzers are not added, even though 'IsAotComptabile' is set in the parent 'Directory.Build.props' -->
7+
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsAotCompatible>
68
</PropertyGroup>
79

810
<ItemGroup>
@@ -13,4 +15,10 @@
1315
<ProjectReference Include="..\AppCoreNet.Extensions.Hosting.Plugins\AppCoreNet.Extensions.Hosting.Plugins.csproj" />
1416
</ItemGroup>
1517

18+
<ItemGroup>
19+
<Compile Include="..\..\..\DependencyInjection\src\AppCoreNet.Extensions.DependencyInjection.Abstractions\ServiceCollectionServiceProvider.cs">
20+
<Link>ServiceCollectionServiceProvider.cs</Link>
21+
</Compile>
22+
</ItemGroup>
23+
1624
</Project>

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins.AspNetCore.Mvc/PluginsMvcBuilderExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright (c) The AppCore .NET project.
33

44
using System.Collections.Generic;
5+
using System.Diagnostics.CodeAnalysis;
56
using System.Reflection;
67
using AppCoreNet.Diagnostics;
78
using AppCoreNet.Extensions.Hosting.Plugins;
@@ -14,6 +15,8 @@ namespace AppCoreNet.Extensions.DependencyInjection;
1415
/// <summary>
1516
/// Provides extension methods to register plugins with MVC.
1617
/// </summary>
18+
[RequiresUnreferencedCode("Uses reflection to discover services.")]
19+
[RequiresDynamicCode("Creates the generic plugin service collection.")]
1720
public static class PluginsMvcBuilderExtensions
1821
{
1922
private static void AddApplicationParts(ApplicationPartManager manager, Assembly assembly)

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins.AspNetCore.Mvc/ServiceCollectionServiceProvider.cs

Lines changed: 0 additions & 100 deletions
This file was deleted.

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins/AppCoreNet.Extensions.Hosting.Plugins.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<PropertyGroup>
44
<TargetFramework>net8.0</TargetFramework>
55
<Description>Provides plugin extensions to the Microsoft.Extensions.Hosting framework.</Description>
6+
<!-- Without this, ILLink analyzers are not added, even though 'IsAotComptabile' is set in the parent 'Directory.Build.props' -->
7+
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsAotCompatible>
68
</PropertyGroup>
79

810
<ItemGroup>

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins/DependencyInjection/FacilityExtensionWrapper.cs

Lines changed: 0 additions & 23 deletions
This file was deleted.

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins/DependencyInjection/PluginFacilityResolver.cs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.Linq;
78
using AppCoreNet.Diagnostics;
89
using AppCoreNet.Extensions.Hosting.Plugins;
@@ -13,6 +14,7 @@ namespace AppCoreNet.Extensions.DependencyInjection.Facilities;
1314
/// <summary>
1415
/// Builds an <see cref="IEnumerable{T}"/> of <see cref="IFacility"/> by scanning plugin assemblies.
1516
/// </summary>
17+
[RequiresUnreferencedCode("Uses reflection to discover types.")]
1618
public class PluginFacilityResolver : IFacilityResolver, IFacilityExtensionResolver
1719
{
1820
private readonly IPluginManager _pluginManager;
@@ -36,30 +38,28 @@ IEnumerable<IFacility> IFacilityResolver.Resolve()
3638
}
3739
}
3840

39-
private IFacilityExtension<IFacility> CreateExtension(IPluginService<object> pluginService)
40-
{
41-
Type extensionType = pluginService.GetType()
42-
.GetInterfaces()
43-
.First(i => i.GetGenericTypeDefinition() == typeof(IPluginService<>))
44-
.GenericTypeArguments[0];
45-
46-
Type contractType = extensionType.GenericTypeArguments[0];
47-
Type extensionWrapperType = typeof(FacilityExtensionWrapper<>).MakeGenericType(contractType);
48-
49-
return (IFacilityExtension<IFacility>)System.Activator.CreateInstance(
50-
extensionWrapperType,
51-
pluginService.Instance)!;
52-
}
53-
5441
/// <inheritdoc />
55-
IEnumerable<IFacilityExtension<IFacility>> IFacilityExtensionResolver.Resolve(Type facilityType)
42+
IEnumerable<IFacilityExtension> IFacilityExtensionResolver.Resolve(Type facilityType)
5643
{
57-
IPluginServiceCollection<object> services = _pluginManager.GetServices(
58-
typeof(IFacilityExtension<>).MakeGenericType(facilityType));
44+
IPluginServiceCollection<object> services = _pluginManager.GetServices(typeof(IFacilityExtension));
5945

6046
foreach (IPluginService<object> service in services)
6147
{
62-
yield return CreateExtension(service);
48+
if (!IsCompatibleExtensionType(service.Instance.GetType(), facilityType))
49+
continue;
50+
51+
yield return (IFacilityExtension)service.Instance;
52+
}
53+
54+
static bool IsCompatibleExtensionType(Type extensionType, Type facilityType)
55+
{
56+
IEnumerable<Type> extensionInterfaces =
57+
extensionType.GetInterfaces()
58+
.Where(t => t.IsGenericType
59+
&& t.GetGenericTypeDefinition() == typeof(IFacilityExtension<>));
60+
61+
IEnumerable<Type> extendedFacilityTypes = extensionInterfaces.Select(t => t.GenericTypeArguments[0]);
62+
return extendedFacilityTypes.Any(t => t.IsAssignableFrom(facilityType));
6363
}
6464
}
6565
}

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins/DependencyInjection/PluginReflectionBuilderExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright (c) The AppCore .NET project.
33

44
using System;
5+
using System.Diagnostics.CodeAnalysis;
56
using AppCoreNet.Diagnostics;
67
using AppCoreNet.Extensions.DependencyInjection.Facilities;
78

@@ -11,6 +12,7 @@ namespace AppCoreNet.Extensions.DependencyInjection;
1112
/// <summary>
1213
/// Provides extension methods to register services and facilities from plugins.
1314
/// </summary>
15+
[RequiresUnreferencedCode("Uses reflection to discover types.")]
1416
public static class PluginReflectionBuilderExtensions
1517
{
1618
/// <summary>

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins/DependencyInjection/PluginServiceCollectionExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Copyright (c) The AppCore .NET project.
33

44
using System;
5+
using System.Diagnostics.CodeAnalysis;
56
using AppCoreNet.Diagnostics;
67
using AppCoreNet.Extensions.DependencyInjection.Activator;
78
using AppCoreNet.Extensions.Hosting.Plugins;
@@ -15,6 +16,8 @@ namespace AppCoreNet.Extensions.DependencyInjection;
1516
/// <summary>
1617
/// Provides extension methods to register plugins.
1718
/// </summary>
19+
[RequiresUnreferencedCode("Uses reflection to discover services.")]
20+
[RequiresDynamicCode("Creates the generic plugin service collection.")]
1821
public static class PluginServiceCollectionExtensions
1922
{
2023
private static readonly object _pluginManagerFactorySyncRoot = new();

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins/DependencyInjection/PluginServiceDescriptorResolver.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.Linq;
78
using AppCoreNet.Diagnostics;
89
using AppCoreNet.Extensions.Hosting.Plugins;
@@ -15,6 +16,7 @@ namespace AppCoreNet.Extensions.DependencyInjection;
1516
/// <summary>
1617
/// Builds an <see cref="IEnumerable{T}"/> of <see cref="ServiceDescriptor"/> by scanning plugin assemblies.
1718
/// </summary>
19+
[RequiresUnreferencedCode("Uses reflection to discover services.")]
1820
public class PluginServiceDescriptorResolver : IServiceDescriptorResolver
1921
{
2022
private readonly List<Predicate<Type>> _filters = new();

Hosting/src/AppCoreNet.Extensions.Hosting.Plugins/Plugin.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections;
66
using System.Collections.Concurrent;
77
using System.Collections.Generic;
8+
using System.Diagnostics.CodeAnalysis;
89
using System.Linq;
910
using System.Reflection;
1011
using AppCoreNet.Diagnostics;
@@ -15,6 +16,8 @@
1516

1617
namespace AppCoreNet.Extensions.Hosting.Plugins;
1718

19+
[RequiresUnreferencedCode("Uses reflection to discover services.")]
20+
[RequiresDynamicCode("Dynamically creates generic types.")]
1821
internal sealed class Plugin : IPlugin, IServiceProviderIsService
1922
{
2023
private readonly IActivator _activator;

0 commit comments

Comments
 (0)