【问题标题】:How to use DI with Microsoft Graph如何在 Microsoft Graph 中使用 DI
【发布时间】:2023-03-08 13:30:02
【问题描述】:

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

于是我创建了一个配置类:

public class GraphConfiguration
    {
        public static void Configure(IServiceCollection services, IConfiguration configuration)
        {
            //Look at appsettings.Development.json | https://docs.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);     

        }
    }

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

 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);
            }
        }      
    }

但我认为我在 Startupcs 中缺少一步。我如何实际将其注入所有控制器中?

【问题讨论】:

    标签: c# .net asp.net-core dependency-injection asp.net-web-api2


    【解决方案1】:

    我认为你应该让你的方法返回一个 IServiceCollection,然后在你的 startup.cs 中调用它。

        public class GraphConfiguration
            {
                public static IServiceCollection AddGraphComponent(this IServiceCollection services, IConfiguration configuration)
                {
                    //your code
    
                    services.AddSingleton<ClientCredentialProvider>(x =>
                    {
                         return new GraphServiceClient(authenticationProvider);
                    });
    
                    services.AddSingleton<GraphServiceClient>(x =>
                    {
                         return new ClientCredentialProvider(confidentialClientApplication);
                    });    
    
                    return services    
                }
            }
    

    然后在你的startup.cs的ConfigureServices方法中调用这个方法。

     services.AddGraphComponent(yourConfiguration);
    

    【讨论】:

    • 我的代码中不需要这样的东西:? services.Add(graphServiceClient);
    • 我怀疑您可能还需要在 GraphConfiguration 类中返回 graphServiceClient 并使其成为单例。
    【解决方案2】:

    我建议使用 DI 容器注册 GraphServiceClient

    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://docs.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);
    
            services.AddScoped<GraphServiceClient>(sp => {
                return new GraphServiceClient(authenticationProvider);
            });
    
            return services;
        }
    }
    

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

    【讨论】:

    • Graph SDK 第 4 版中删除了 IGraphServiceClient,记录在 devblogs.microsoft.com/microsoft365dev/…
    • @ChrisLawrence 感谢您的更新。我会看看如何重新格式化答案以匹配这些新信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多