microsoft-identity-web icon indicating copy to clipboard operation
microsoft-identity-web copied to clipboard

[Feature Request] Use GraphServiceClient as singleton

Open xubinzheng opened this issue 3 years ago • 1 comments

Is your feature request related to a problem? Please describe. Currently the lifetime for GraphServiceClient is scoped. It makes developer extremely hard to org their code. Currently, the only approach is to reference the Graph client in the controller and pass it all the way down to where we need to call MS Graph.

It would be very help to have an option to create the Graph client as a singleton.

Describe the solution you'd like It would be very helpful to have an option to create the Graph client as a singleton.

Additional context Currently, referencing the GraphServiceClient in a singleton will throw the exception below during service startup

Unhandled exception. System.ObjectDisposedException: The CancellationTokenSource has been disposed. at System.Threading.CancellationTokenSource.ThrowObjectDisposedException() at System.Threading.CancellationTokenSource.Cancel() at Azure.Extensions.AspNetCore.Configuration.Secrets.AzureKeyVaultConfigurationProvider.Dispose(Boolean disposing) at Azure.Extensions.AspNetCore.Configuration.Secrets.AzureKeyVaultConfigurationProvider.Dispose() at Microsoft.Extensions.Configuration.ConfigurationRoot.Dispose() at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.DisposeAsync() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Hosting.WebHost.DisposeServiceProviderAsync(IServiceProvider serviceProvider) at Microsoft.AspNetCore.Hosting.WebHost.DisposeAsync() at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token) at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host) at MyApps.Program.Main(String[] args) in C:\Desktop\Projects<>\Program.cs:line 35

xubinzheng avatar Mar 12 '22 00:03 xubinzheng

@xubinzheng The point of Dependency injection is that you don't have to worry how it's created?

Currently, the only approach is to reference the Graph client in the controller and pass it all the way down to where we need to call MS Graph.

You can have your class "all the way down" request an instance of the GraphServiceClient right? As long as the all the way down class is added as scoped or transient to the service collection that is. Something like:

public class AllTheWayDown
{
    private readonly GraphServiceClient client;
    public AllTheWayDown(GraphServiceClient client) {
        this.client = client
    }
}


// Startup
services.AddScoped<AllTheWayDown>();

// Controller
private readonly AllTheWayDown classCallingGraph;
public {name}Controller(AllTheWayDown atwd) {
  classCallingGraph = atwd;
}

svrooij avatar Jun 27 '22 15:06 svrooij