Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Extensions] Add AOT compatibility attributes to Microsoft.Extensions.Azure #41936

Merged
merged 5 commits into from
Feb 14, 2024
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 sdk/core/Azure.Core/api/Azure.Core.net6.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,7 @@ public partial interface IAzureClientFactoryBuilder
}
public partial interface IAzureClientFactoryBuilderWithConfiguration<in TConfiguration> : Azure.Core.Extensions.IAzureClientFactoryBuilder
{
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
Azure.Core.Extensions.IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, TOptions>(TConfiguration configuration) where TOptions : class;
}
public partial interface IAzureClientFactoryBuilderWithCredential
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Diagnostics.CodeAnalysis;

namespace Azure.Core.Extensions
{
Expand All @@ -17,6 +18,6 @@ public interface IAzureClientFactoryBuilder
/// <typeparam name="TOptions">The client options type used the client.</typeparam>
/// <param name="clientFactory">The factory, that given the instance of options, returns a client instance.</param>
/// <returns><see cref="IAzureClientBuilder{TClient,TOptions}"/> that allows customizing the client registration.</returns>
IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, TOptions>(Func<TOptions, TClient> clientFactory) where TOptions : class;
IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(Func<TOptions, TClient> clientFactory) where TOptions : class;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Diagnostics.CodeAnalysis;

namespace Azure.Core.Extensions
{
/// <summary>
Expand All @@ -15,6 +17,8 @@ public interface IAzureClientFactoryBuilderWithConfiguration<in TConfiguration>
/// <typeparam name="TOptions">The client options type used the client.</typeparam>
/// <param name="configuration">Instance of <typeparamref name="TConfiguration"/> to use.</param>
/// <returns><see cref="IAzureClientBuilder{TClient,TOptions}"/> that allows customizing the client registration.</returns>
IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, TOptions>(TConfiguration configuration) where TOptions : class;
[RequiresUnreferencedCode("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
[RequiresDynamicCode("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(TConfiguration configuration) where TOptions : class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Diagnostics.CodeAnalysis;

namespace Azure.Core.Extensions
{
Expand All @@ -18,6 +19,6 @@ public interface IAzureClientFactoryBuilderWithCredential
/// <param name="clientFactory">The factory, that given the instance of options and credential, returns a client instance.</param>
/// <param name="requiresCredential">Specifies whether the credential is optional (client supports anonymous authentication).</param>
/// <returns><see cref="IAzureClientBuilder{TClient,TOptions}"/> that allows customizing the client registration.</returns>
IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, TOptions>(Func<TOptions, TokenCredential, TClient> clientFactory, bool requiresCredential = true) where TOptions : class;
IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(Func<TOptions, TokenCredential, TClient> clientFactory, bool requiresCredential = true) where TOptions : class;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Diagnostics.CodeAnalysis;

namespace Microsoft.Extensions.Azure
{
Expand Down Expand Up @@ -78,6 +79,8 @@ public static IAzureClientBuilder<TClient, TOptions> ConfigureOptions<TClient, T
/// <param name="builder">The client builder instance.</param>
/// <param name="configuration">The configuration instance to use.</param>
/// <returns>The client builder instance.</returns>
[RequiresUnreferencedCode("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
[RequiresDynamicCode("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
public static IAzureClientBuilder<TClient, TOptions> ConfigureOptions<TClient, TOptions>(this IAzureClientBuilder<TClient, TOptions> builder, IConfiguration configuration) where TOptions : class
{
return builder.ConfigureOptions(options => configuration.Bind(options));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Diagnostics.CodeAnalysis;
using Azure.Core;
using Azure.Core.Extensions;
using Microsoft.Extensions.Configuration;
Expand All @@ -25,12 +26,16 @@ internal AzureClientFactoryBuilder(IServiceCollection serviceCollection)
_serviceCollection = serviceCollection;
}

IAzureClientBuilder<TClient, TOptions> IAzureClientFactoryBuilder.RegisterClientFactory<TClient, TOptions>(Func<TOptions, TClient> clientFactory)
IAzureClientBuilder<TClient, TOptions> IAzureClientFactoryBuilder.RegisterClientFactory<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(
Func<TOptions, TClient> clientFactory)
{
return ((IAzureClientFactoryBuilderWithCredential)this).RegisterClientFactory<TClient, TOptions>((options, _) => clientFactory(options));
}

IAzureClientBuilder<TClient, TOptions> IAzureClientFactoryBuilderWithConfiguration<IConfiguration>.RegisterClientFactory<TClient, TOptions>(IConfiguration configuration)
[RequiresUnreferencedCode("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
[RequiresDynamicCode("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
IAzureClientBuilder<TClient, TOptions> IAzureClientFactoryBuilderWithConfiguration<IConfiguration>.RegisterClientFactory<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(
IConfiguration configuration)
{
var credentialsFromConfig = ClientFactory.CreateCredential(configuration);
var clientBuilder =((IAzureClientFactoryBuilderWithCredential)this).RegisterClientFactory<TClient, TOptions>(
Expand Down Expand Up @@ -73,6 +78,8 @@ public AzureClientFactoryBuilder ConfigureDefaults(Action<ClientOptions, IServic
/// </summary>
/// <param name="configuration">The configuration instance.</param>
/// <returns>This instance.</returns>
[RequiresUnreferencedCode("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
[RequiresDynamicCode("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
public AzureClientFactoryBuilder ConfigureDefaults(IConfiguration configuration)
{
ConfigureDefaults(configuration.Bind);
Expand All @@ -87,7 +94,8 @@ public AzureClientFactoryBuilder ConfigureDefaults(IConfiguration configuration)
return this;
}

IAzureClientBuilder<TClient, TOptions> IAzureClientFactoryBuilderWithCredential.RegisterClientFactory<TClient, TOptions>(Func<TOptions, TokenCredential, TClient> clientFactory, bool requiresCredential)
IAzureClientBuilder<TClient, TOptions> IAzureClientFactoryBuilderWithCredential.RegisterClientFactory<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(
Func<TOptions, TokenCredential, TClient> clientFactory, bool requiresCredential)
{
return RegisterClientFactory<TClient, TOptions>((options, credential, _) => clientFactory(options, credential), requiresCredential);
}
Expand Down Expand Up @@ -119,7 +127,9 @@ public AzureClientFactoryBuilder UseCredential(Func<IServiceProvider, TokenCrede
/// <typeparam name="TClient">The type of the client.</typeparam>
/// <typeparam name="TOptions">The type of the client options.</typeparam>
/// <returns>The <see cref="IAzureClientBuilder{TClient, TOptions}"/> to allow client configuration.</returns>
public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, TOptions>(Func<TOptions, TClient> factory) where TOptions : class
public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(
Func<TOptions, TClient> factory)
where TOptions : class
{
return RegisterClientFactory<TClient, TOptions>((options, _, _) => factory(options), false);
}
Expand All @@ -130,7 +140,9 @@ public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, TOptions>(Func<
/// <typeparam name="TClient">The type of the client.</typeparam>
/// <typeparam name="TOptions">The type of the client options.</typeparam>
/// <returns>The <see cref="IAzureClientBuilder{TClient, TOptions}"/> to allow client configuration.</returns>
public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, TOptions>(Func<TOptions, TokenCredential, TClient> factory) where TOptions : class
public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(
Func<TOptions, TokenCredential, TClient> factory)
where TOptions : class
{
return RegisterClientFactory<TClient, TOptions>((options, credential, _) => factory(options, credential), true);
}
Expand All @@ -142,7 +154,9 @@ public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, TOptions>(Func<
/// <typeparam name="TClient">The type of the client.</typeparam>
/// <typeparam name="TOptions">The type of the client options.</typeparam>
/// <returns>The <see cref="IAzureClientBuilder{TClient, TOptions}"/> to allow client configuration.</returns>
public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, TOptions>(Func<TOptions, IServiceProvider, TClient> factory) where TOptions : class
public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(
Func<TOptions, IServiceProvider, TClient> factory)
where TOptions : class
{
return RegisterClientFactory<TClient, TOptions>((options, _, provider) => factory(options, provider), true);
}
Expand All @@ -154,12 +168,17 @@ public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, TOptions>(Func<
/// <typeparam name="TClient">The type of the client.</typeparam>
/// <typeparam name="TOptions">The type of the client options.</typeparam>
/// <returns>The <see cref="IAzureClientBuilder{TClient, TOptions}"/> to allow client configuration.</returns>
public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, TOptions>(Func<TOptions, TokenCredential, IServiceProvider, TClient> factory) where TOptions : class
public IAzureClientBuilder<TClient, TOptions> AddClient<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(
Func<TOptions, TokenCredential, IServiceProvider, TClient> factory)
where TOptions : class
{
return RegisterClientFactory<TClient, TOptions>((options, credential, provider) => factory(options, credential, provider), true);
}

private IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, TOptions>(Func<TOptions, TokenCredential, IServiceProvider, TClient> clientFactory, bool requiresCredential) where TOptions : class
private IAzureClientBuilder<TClient, TOptions> RegisterClientFactory<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>(
Func<TOptions, TokenCredential, IServiceProvider, TClient> clientFactory,
bool requiresCredential)
where TOptions : class
{
var clientRegistration = new ClientRegistration<TClient>(DefaultClientName, requiresCredential, (provider, options, credential) => clientFactory((TOptions) options, credential, provider));
_serviceCollection.AddSingleton(clientRegistration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Diagnostics.CodeAnalysis;
using Azure.Core;
using Microsoft.Extensions.Configuration;

Expand All @@ -24,7 +25,12 @@ public abstract class AzureComponentFactory
/// <param name="serviceVersion">The value of ServiceVersion enum to use, null to use the default.</param>
/// <param name="configuration">The <see cref="IConfiguration"/> instance to apply to options.</param>
/// <returns>A new instance of <paramref name="optionsType"/>.</returns>
public abstract object CreateClientOptions(Type optionsType, object serviceVersion, IConfiguration configuration);
[RequiresUnreferencedCode("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
[RequiresDynamicCode("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
public abstract object CreateClientOptions(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type optionsType,
object serviceVersion,
IConfiguration configuration);

/// <summary>
/// Creates a new client instance using the provided configuration to map constructor parameters from.
Expand All @@ -35,6 +41,11 @@ public abstract class AzureComponentFactory
/// <param name="credential">The <see cref="TokenCredential"/> object to use if required by constructor, if null no .</param>
/// <param name="clientOptions">The client </param>
/// <returns></returns>
public abstract object CreateClient(Type clientType, IConfiguration configuration, TokenCredential credential, object clientOptions);
[RequiresUnreferencedCode("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
public abstract object CreateClient(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type clientType,
IConfiguration configuration,
TokenCredential credential,
object clientOptions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Microsoft.Extensions.Options;

namespace Microsoft.Extensions.Azure
{
internal class AzureClientFactory<TClient, TOptions>: IAzureClientFactory<TClient>, IDisposable, IAsyncDisposable
internal class AzureClientFactory<TClient, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TOptions>
: IAzureClientFactory<TClient>, IDisposable, IAsyncDisposable
{
private readonly Dictionary<string, ClientRegistration<TClient>> _clientRegistrations;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License.

using System;
using System.Diagnostics.CodeAnalysis;
using Azure.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
Expand All @@ -25,7 +26,12 @@ public override TokenCredential CreateTokenCredential(IConfiguration configurati
return ClientFactory.CreateCredential(configuration) ?? _globalOptions.CurrentValue.CredentialFactory(_serviceProvider);
}

public override object CreateClientOptions(Type optionsType, object serviceVersion, IConfiguration configuration)
[RequiresUnreferencedCode("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
[RequiresDynamicCode("Binding strongly typed objects to configuration values requires generating dynamic code at runtime, for example instantiating generic types. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
public override object CreateClientOptions(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type optionsType,
object serviceVersion,
IConfiguration configuration)
{
if (optionsType == null) throw new ArgumentNullException(nameof(optionsType));
var options = ClientFactory.CreateClientOptions(serviceVersion, optionsType);
Expand All @@ -41,7 +47,12 @@ public override object CreateClientOptions(Type optionsType, object serviceVersi
return options;
}

public override object CreateClient(Type clientType, IConfiguration configuration, TokenCredential credential, object clientOptions)
[RequiresUnreferencedCode("Binding strongly typed objects to configuration values is not supported with trimming. Use the Configuration Binder Source Generator (EnableConfigurationBindingGenerator=true) instead.")]
public override object CreateClient(
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type clientType,
IConfiguration configuration,
TokenCredential credential,
object clientOptions)
{
if (clientType == null) throw new ArgumentNullException(nameof(clientType));
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
Expand Down
Loading