如何将 DI 与 Microsoft Graph 结合使用

Lui*_*cia 11 .net c# dependency-injection asp.net-web-api2 asp.net-core

我有一个 .net web api 核心项目,我将调用 microsoft graph

所以我创建了一个配置类:

public class GraphConfiguration
    {
        public static void Configure(IServiceCollection services, IConfiguration configuration)
        {
            //Look at appsettings.Development.json | https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1
            var graphConfig = new AppSettingsSection();
            configuration.GetSection("AzureAD").Bind(graphConfig);

            IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
                .Create(graphConfig.ClientId)
                .WithTenantId(graphConfig.TenantId)
                .WithClientSecret(graphConfig.ClientSecret)
                .Build();
                
            ClientCredentialProvider authenticationProvider = new ClientCredentialProvider(confidentialClientApplication);
            GraphServiceClient graphServiceClient = new GraphServiceClient(authenticationProvider);     

        }
    }
Run Code Online (Sandbox Code Playgroud)

在我的控制器中我有这个:

 public class UserController : ControllerBase
    {
        private TelemetryClient telemetry;
        private readonly ICosmosStore<Partner> _partnerCosmosStore;
        private readonly GraphServiceClient _graphServiceClient;


        // Use constructor injection to get a TelemetryClient instance.
        public UserController(TelemetryClient telemetry,ICosmosStore<Partner> partnerCosmosStore, GraphServiceClient graphServiceClient)
        {
            this.telemetry = telemetry;
             _partnerCosmosStore = partnerCosmosStore; 
             _graphServiceClient = graphServiceClient;          
        }

        /// <summary>
        /// Gets all partners
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult> GetUsers()
        {
            this.telemetry.TrackEvent("GetPartners");
        
            try
            {
                var me = await _graphServiceClient.Me.Request().WithForceRefresh(true).GetAsync();
                return Ok(me);
            }
            catch (Exception ex)
            {
                string guid = Guid.NewGuid().ToString();
                var dt = new Dictionary<string, string>
                {
                    { "Error Lulo: ", guid }
                };
                telemetry.TrackException(ex, dt);
                return BadRequest("Error Lulo: " + guid);
            }
        }      
    }
Run Code Online (Sandbox Code Playgroud)

但我认为我在 Startupcs 中错过了一步。我如何将它实际注入到所有控制器中?

Nko*_*osi 14

我建议GraphServiceClient使用 DI 容器注册

public static class GraphConfiguration {
    //Called in Startup - services.ConfigureGraphComponent(configuration)
    public static IServiceCollection ConfigureGraphComponent(this IServiceCollection services, IConfiguration configuration) {
        //Look at appsettings.Development.json | https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-2.1
        
        AppSettingsSection graphConfig = configuration.GetSection("AzureAD").Get<AppSettingsSection>();

        IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
            .Create(graphConfig.ClientId)
            .WithTenantId(graphConfig.TenantId)
            .WithClientSecret(graphConfig.ClientSecret)
            .Build();
            
        ClientCredentialProvider authenticationProvider = new ClientCredentialProvider(confidentialClientApplication);

        //you can use a single client instance for the lifetime of the application
        services.AddSingleton<GraphServiceClient>(sp => {
            return new GraphServiceClient(authenticationProvider);
        });

        return services;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样容器就会知道如何在解析控制器时注入所需的依赖项