Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/assets.msbuildproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<PropertyGroup>
<TargetFramework>netstandard1.0</TargetFramework>
<IsPackable>false</IsPackable>
<NoWarn>$(NoWarn);NETSDK1215</NoWarn>
</PropertyGroup>
<ItemGroup>
<None Include="**\*.*" Exclude="*.msbuildproj;obj\**\*.*" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.0' ">
<CheckNotRecommendedTargetFramework>false</CheckNotRecommendedTargetFramework>
</PropertyGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.0' ">
<Compile Remove="netstandard2.0\**\*.cs;net#.0\**\*.cs" />
<None Include="netstandard2.0\**\*.cs;net#.0\**\*.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ public ModelMetadata GetMetadataForType( Type modelType ) =>
throw new NotImplementedException();
}

[UnconditionalSuppressMessage( "ILLink", "IL2092" )]
[UnconditionalSuppressMessage( "ILLink", "IL2093" )]
private sealed class StubModelTypeBuilder : IModelTypeBuilder
{
public Type NewActionParameters( IEdmModel model, IEdmAction action, string controllerName, ApiVersion apiVersion ) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<AssemblyTitle>ASP.NET Core API Versioning API Explorer for OData v4.0</AssemblyTitle>
<Description>The API Explorer extensions for ASP.NET Core API Versioning and OData v4.0.</Description>
<PackageTags>Asp;AspNet;AspNetCore;Versioning;ApiExplorer;OData</PackageTags>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<AssemblyTitle>ASP.NET Core API Versioning with OData v4.0</AssemblyTitle>
<Description>A service API versioning library for Microsoft ASP.NET Core with OData v4.0.</Description>
<PackageTags>Asp;AspNet;AspNetCore;Versioning;OData</PackageTags>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ internal static ApplicationPartManager GetOrCreateApplicationPartManager( this I
return partManager;
}

[UnconditionalSuppressMessage( "ILLink", "IL2072", Justification = "Model configuration types are never trimmed" )]
internal static void AddModelConfigurationsAsServices( this IServiceCollection services, ApplicationPartManager partManager )
{
var feature = new ModelConfigurationFeature();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ private static Type GetDefaultApplicationModelProviderType()
return Type.GetType( $"{TypeName}, {assemblyName}", throwOnError: true, ignoreCase: false )!;
}

private static Func<IOptions<ODataOptions>, IApplicationModelProvider> CreateActivator( Type type )
private static Func<IOptions<ODataOptions>, IApplicationModelProvider> CreateActivator(
[DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicConstructors )] Type type )
{
var options = Parameter( typeof( IOptions<ODataOptions> ), "options" );
var @new = New( type.GetConstructors()[0], options );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
namespace Asp.Versioning.ApiExplorer;

using Microsoft.Extensions.Options;
using static System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes;

/// <summary>
/// Represents a factory to create API explorer options.
/// </summary>
/// <typeparam name="T">The type of options to create.</typeparam>
[CLSCompliant( false )]
public class ApiExplorerOptionsFactory<T> : OptionsFactory<T> where T : ApiExplorerOptions
public class ApiExplorerOptionsFactory<[DynamicallyAccessedMembers( PublicParameterlessConstructor )] T>
: OptionsFactory<T> where T : ApiExplorerOptions
{
private readonly IOptions<ApiVersioningOptions> optionsHolder;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<AssemblyTitle>ASP.NET Core API Versioning API Explorer</AssemblyTitle>
<Description>The API Explorer extensions for ASP.NET Core API Versioning.</Description>
<PackageTags>Asp;AspNet;AspNetCore;Versioning;ApiExplorer</PackageTags>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<Description>A service API versioning library for Microsoft ASP.NET Core MVC.</Description>
<PackageTags>Asp;AspNet;AspNetCore;MVC;Versioning</PackageTags>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsTrimmable>true</IsTrimmable>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Runtime.CompilerServices;
using static ServiceDescriptor;
using static System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes;

/// <summary>
/// Provides ASP.NET Core MVC specific extension methods for <see cref="IApiVersioningBuilder"/>.
Expand Down Expand Up @@ -85,7 +86,11 @@ private static object CreateInstance( this IServiceProvider services, ServiceDes
return ActivatorUtilities.GetServiceOrCreateInstance( services, descriptor.ImplementationType! );
}

private static void TryReplace<TService, TImplementation, TReplacement>( this IServiceCollection services )
private static void TryReplace<
TService,
TImplementation,
[DynamicallyAccessedMembers( NonPublicConstructors | PublicConstructors )]
TReplacement>( this IServiceCollection services )
{
var serviceType = typeof( TService );
var implementationType = typeof( TImplementation );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,30 @@ public ApiVersionUrlHelper( ActionContext actionContext, IUrlHelper url )
return current;
}

if ( current is not RouteValueDictionary values )
RouteValueDictionary values;

if ( current is null )
{
values = new() { { key, value } };
return values;
}

if ( current is RouteValueDictionary dictionary )
{
values = dictionary;
}
else if ( current is IEnumerable<KeyValuePair<string, object?>> kvps )
{
values = current == null ? new() : new( current );
values = [];

foreach ( var kvp in kvps )
{
values.Add( kvp.Key, kvp.Value );
}
}
else
{
return current;
}

if ( !values.ContainsKey( key ) )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
<IsAotCompatible>true</IsAotCompatible>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.1' ">
<CheckNotRecommendedTargetFramework>false</CheckNotRecommendedTargetFramework>
</PropertyGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.1' ">
<Compile Remove="net#.0\**\*.cs" />
<None Include="net#.0\**\*.cs" />
Expand Down
1 change: 1 addition & 0 deletions src/Common/src/Common.Backport/Common.Backport.msbuildproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.Build.NoTargets/3.3.0">
<PropertyGroup>
<TargetFramework>netstandard1.0</TargetFramework>
<NoWarn>$(NoWarn);NETSDK1215</NoWarn>
</PropertyGroup>
<ItemGroup>
<None Include="**\*.*" Exclude="*.msbuildproj;obj\**\*.*" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ public static IActionConventionBuilder<TController> Action<TController, TResult>
/// If there is only one corresponding match found, then the <paramref name="argumentTypes">argument types</paramref> are ignored;
/// otherwise, the <paramref name="argumentTypes">argument types</paramref> are used for method overload resolution. Action
/// methods that have the <see cref="NonActionAttribute"/> applied will also be ignored.</remarks>
#if !NETFRAMEWORK
[UnconditionalSuppressMessage( "ILLink", "IL2072", Justification = "Controller types are never trimmed" )]
#endif
public static IActionConventionBuilder Action( this IActionConventionBuilder builder, string methodName, params Type[] argumentTypes )
{
ArgumentNullException.ThrowIfNull( builder );
Expand Down
11 changes: 9 additions & 2 deletions src/Common/src/Common.Mvc/Conventions/ActionMethodResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@ namespace Asp.Versioning.Conventions;
#if NETFRAMEWORK
using System.Web.Http;
#endif
using static System.Reflection.BindingFlags;

internal static class ActionMethodResolver
{
internal static MethodInfo Resolve( Type controllerType, string methodName, Type[] argumentTypes )
internal static MethodInfo Resolve(
#if !NETFRAMEWORK
[DynamicallyAccessedMembers( DynamicallyAccessedMemberTypes.PublicMethods )]
#endif
Type controllerType,
string methodName,
Type[] argumentTypes )
{
var methods = controllerType.GetRuntimeMethods().Where( m => m.Name == methodName && IsAction( m ) ).ToArray();
var methods = controllerType.GetMethods( Instance | Public ).Where( m => m.Name == methodName && IsAction( m ) ).ToArray();

switch ( methods.Length )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ public static IActionConventionBuilder<TController> Action<TController, TResult>
/// If there is only one corresponding match found, then the <paramref name="argumentTypes">argument types</paramref> are ignored;
/// otherwise, the <paramref name="argumentTypes">argument types</paramref> are used for method overload resolution. Action
/// methods that have the <see cref="NonActionAttribute"/> applied will also be ignored.</remarks>
#if !NETFRAMEWORK
[UnconditionalSuppressMessage( "ILLink", "IL2072", Justification = "Controller types are never trimmed" )]
#endif
public static IActionConventionBuilder Action( this IControllerConventionBuilder builder, string methodName, params Type[] argumentTypes )
{
ArgumentNullException.ThrowIfNull( builder );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Asp.Versioning.Conventions;
using System.Web.Http;
using System.Web.Http.Controllers;
#endif
using static System.Reflection.BindingFlags;

/// <summary>
/// Provides extension methods for the <see cref="ODataActionQueryOptionsConventionBuilder"/>
Expand Down Expand Up @@ -187,6 +188,9 @@ public static ODataActionQueryOptionsConventionBuilder<TController> Action<TCont
/// If there is only one corresponding match found, then the <paramref name="argumentTypes">argument types</paramref> are ignored;
/// otherwise, the <paramref name="argumentTypes">argument types</paramref> are used for method overload resolution. Action
/// methods that have the <see cref="NonActionAttribute"/> applied will also be ignored.</remarks>
#if !NETFRAMEWORK
[UnconditionalSuppressMessage( "ILLink", "IL2075", Justification = "Controller types and actions are never trimmed" )]
#endif
public static ODataActionQueryOptionsConventionBuilder Action(
this IODataActionQueryOptionsConventionBuilder builder,
string methodName,
Expand All @@ -197,7 +201,7 @@ public static ODataActionQueryOptionsConventionBuilder Action(

string message;
var methods = builder.ControllerType
.GetRuntimeMethods()
.GetMethods( Instance | Public )
.Where( m => m.Name == methodName && IsAction( m ) )
.ToArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ internal static class EdmExtensions
return null;
}

#if !NETFRAMEWORK
[UnconditionalSuppressMessage( "ILLink", "IL2057", Justification = "The types being referenced are well-known and will not be trimmed." )]
#endif
private static Type? DeriveFromWellKnowPrimitive( string edmFullName ) => edmFullName switch
{
"Edm.String" or "Edm.Byte" or "Edm.SByte" or "Edm.Int16" or "Edm.Int32" or "Edm.Int64" or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ internal ClassProperty( PropertyInfo clrProperty, Type propertyType )
Attributes = clrProperty.DeclaredAttributes().ToArray();
}

#if !NETFRAMEWORK
[UnconditionalSuppressMessage( "ILLink", "IL2072" )]
#endif
internal ClassProperty( IEdmOperationParameter parameter, TypeSubstitutionContext context )
{
Name = parameter.Name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ namespace Asp.Versioning.OData;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
#if !NETFRAMEWORK
using static System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes;
#endif
using static System.Globalization.CultureInfo;
using static System.Guid;
using static System.Reflection.BindingFlags;
Expand All @@ -22,6 +25,11 @@ namespace Asp.Versioning.OData;
/// <summary>
/// Represents the default model type builder.
/// </summary>
#if !NETFRAMEWORK
[UnconditionalSuppressMessage( "ILLink", "IL2055")]
[UnconditionalSuppressMessage( "ILLink", "IL2070")]
[UnconditionalSuppressMessage( "ILLink", "IL2073")]
#endif
public sealed class DefaultModelTypeBuilder : IModelTypeBuilder
{
/* design: there is typically a 1:1 relationship between an edm and api version. odata model bound settings
Expand Down Expand Up @@ -59,7 +67,17 @@ private DefaultModelTypeBuilder( bool excludeAdHocModels, bool adHoc )
public DefaultModelTypeBuilder( bool includeAdHocModels = false ) => excludeAdHocModels = !includeAdHocModels;

/// <inheritdoc />
public Type NewStructuredType( IEdmModel model, IEdmStructuredType structuredType, Type clrType, ApiVersion apiVersion )
#if !NETFRAMEWORK
[return: DynamicallyAccessedMembers( Interfaces | PublicProperties )]
#endif
public Type NewStructuredType(
IEdmModel model,
IEdmStructuredType structuredType,
#if !NETFRAMEWORK
[DynamicallyAccessedMembers( Interfaces | PublicProperties )]
#endif
Type clrType,
ApiVersion apiVersion )
{
ArgumentNullException.ThrowIfNull( model );

Expand Down Expand Up @@ -88,6 +106,9 @@ public Type NewStructuredType( IEdmModel model, IEdmStructuredType structuredTyp
}

/// <inheritdoc />
#if !NETFRAMEWORK
[return: DynamicallyAccessedMembers( Interfaces | PublicProperties )]
#endif
public Type NewActionParameters( IEdmModel model, IEdmAction action, string controllerName, ApiVersion apiVersion )
{
ArgumentNullException.ThrowIfNull( model );
Expand Down Expand Up @@ -417,10 +438,6 @@ private static PropertyBuilder AddProperty(
var field = addTo.DefineField( "_" + name, shouldBeAdded, FieldAttributes.Private );
var propertyBuilder = addTo.DefineProperty( name, PropertyAttributes.HasDefault, shouldBeAdded, null );
var getter = addTo.DefineMethod( "get_" + name, propertyMethodAttributes, shouldBeAdded, Type.EmptyTypes );

/* returnType is 'null' instead of type(void) as per docs
* see: https://learn.microsoft.com/en-us/dotnet/api/system.reflection.emit.propertybuilder?view=net-9.0
*/
var setter = addTo.DefineMethod( "set_" + name, propertyMethodAttributes, null, [shouldBeAdded] );
var il = getter.GetILGenerator();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ namespace Asp.Versioning.OData;
using Microsoft.AspNetCore.OData.Formatter;
#endif
using Microsoft.OData.Edm;
#if !NETFRAMEWORK
using static System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes;
#endif

/// <summary>
/// Defines the behavior of a model type builder.
Expand All @@ -26,7 +29,17 @@ public interface IModelTypeBuilder
/// <paramref name="structuredType">structured type</paramref>.</returns>
/// <remarks>If a substitution is not required, the original <paramref name="clrType">CLR type</paramref> is returned. When a substitution
/// <see cref="Type">type</see> is generated, it is performed only once per <paramref name="apiVersion">API version</paramref>.</remarks>
Type NewStructuredType( IEdmModel model, IEdmStructuredType structuredType, Type clrType, ApiVersion apiVersion );
#if !NETFRAMEWORK
[return: DynamicallyAccessedMembers( Interfaces | PublicProperties )]
#endif
Type NewStructuredType(
IEdmModel model,
IEdmStructuredType structuredType,
#if !NETFRAMEWORK
[DynamicallyAccessedMembers( Interfaces | PublicProperties )]
#endif
Type clrType,
ApiVersion apiVersion );

/// <summary>
/// Creates an returns a strongly-typed definition for OData action parameters.
Expand All @@ -39,5 +52,8 @@ public interface IModelTypeBuilder
/// <remarks><see cref="ODataActionParameters">OData action parameters</see> are modeled as a <see cref="Dictionary{TKey,TValue}">dictionary</see>,
/// which is difficult to use effectively by documentation tools such as the API Explorer. The corresponding type is generated only once per
/// <paramref name="apiVersion">API version</paramref>.</remarks>
#if !NETFRAMEWORK
[return: DynamicallyAccessedMembers( Interfaces | PublicProperties )]
#endif
Type NewActionParameters( IEdmModel model, IEdmAction action, string controllerName, ApiVersion apiVersion );
}
Loading
Loading