如何在 .NET Core 3.1 中将 Microsoft Graph 客户端服务添加为 MediatR 服务?
How can you add a Microsoft Graph client service as a MediatR service in .NET Core 3.1?
所以我有一个 .NET Core web API,它有自己的本地数据上下文,我想添加调用 Microsoft Graph 作为下游的功能 API。
但是,当我尝试添加必要的属性来调用图形 API 时,出现构建错误:
Unhandled exception. System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: MediatR.IRequestHandler`2[Application.Users.Me+Query,Microsoft.Graph.User] Lifetime: Transient ImplementationType: Application.Users.Me+Handler': Unable to resolve service for type 'Microsoft.Graph.GraphServiceClient' while attempting to activate 'Application.Users.Me+Handler'.)
这是我的启动 class:
using API.Middleware;
using Application.TestEntities;
using FluentValidation.AspNetCore;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Persistence;
using Microsoft.Identity.Web;
namespace API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(opt =>
{
opt.UseSqlite(Configuration.GetConnectionString("DefaultConnection"));
});
services.AddCors(opt =>
{
opt.AddPolicy("CorsPolicy", policy =>
{
policy.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:3000");
});
});
services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.AddMediatR(typeof(List.Handler).Assembly);
services.AddControllers(opt =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
opt.Filters.Add(new AuthorizeFilter(policy));
})
.AddFluentValidation(cfg => cfg.RegisterValidatorsFromAssemblyContaining<Create>());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<ErrorHandlingMiddleware>();
if (env.IsDevelopment())
{
// app.UseDeveloperExceptionPage();
}
app.UseCors("CorsPolicy");
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
我用于调用下游的应用程序处理程序:
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Microsoft.Graph;
using Microsoft.Identity.Web;
namespace Application.Users
{
public class Me
{
public class Query : IRequest<User> { }
public class Handler : IRequestHandler<Query, User>
{
private readonly ITokenAcquisition _tokenAcquisition;
private readonly GraphServiceClient _graphServiceClient;
public Handler(ITokenAcquisition tokenAcquisition, GraphServiceClient graphServiceClient)
{
_tokenAcquisition = tokenAcquisition;
_graphServiceClient = graphServiceClient;
}
public async Task<User> Handle(Query request, CancellationToken cancellationToken)
{
var user = await _graphServiceClient.Me.Request().GetAsync();
return user;
}
}
}
}
希望我在这里走在正确的轨道上,但如果我不是,请告诉我。
对,所以这是我的一个简单疏忽。
根据@franklores,您需要在启动 class 服务中注册 Microsoft Graph:
services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
将以下内容添加到 appsettings(范围可能不同):
"DownstreamAPI": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read"
},
并确保安装Microsoft.Identity.Web.MicrosoftGraph
以启用AddMicrosoftGraph()
功能。
所以我有一个 .NET Core web API,它有自己的本地数据上下文,我想添加调用 Microsoft Graph 作为下游的功能 API。
但是,当我尝试添加必要的属性来调用图形 API 时,出现构建错误:
Unhandled exception. System.AggregateException: Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: MediatR.IRequestHandler`2[Application.Users.Me+Query,Microsoft.Graph.User] Lifetime: Transient ImplementationType: Application.Users.Me+Handler': Unable to resolve service for type 'Microsoft.Graph.GraphServiceClient' while attempting to activate 'Application.Users.Me+Handler'.)
这是我的启动 class:
using API.Middleware;
using Application.TestEntities;
using FluentValidation.AspNetCore;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Persistence;
using Microsoft.Identity.Web;
namespace API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DataContext>(opt =>
{
opt.UseSqlite(Configuration.GetConnectionString("DefaultConnection"));
});
services.AddCors(opt =>
{
opt.AddPolicy("CorsPolicy", policy =>
{
policy.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:3000");
});
});
services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.AddMediatR(typeof(List.Handler).Assembly);
services.AddControllers(opt =>
{
var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
opt.Filters.Add(new AuthorizeFilter(policy));
})
.AddFluentValidation(cfg => cfg.RegisterValidatorsFromAssemblyContaining<Create>());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<ErrorHandlingMiddleware>();
if (env.IsDevelopment())
{
// app.UseDeveloperExceptionPage();
}
app.UseCors("CorsPolicy");
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
我用于调用下游的应用程序处理程序:
using System.Threading;
using System.Threading.Tasks;
using MediatR;
using Microsoft.Graph;
using Microsoft.Identity.Web;
namespace Application.Users
{
public class Me
{
public class Query : IRequest<User> { }
public class Handler : IRequestHandler<Query, User>
{
private readonly ITokenAcquisition _tokenAcquisition;
private readonly GraphServiceClient _graphServiceClient;
public Handler(ITokenAcquisition tokenAcquisition, GraphServiceClient graphServiceClient)
{
_tokenAcquisition = tokenAcquisition;
_graphServiceClient = graphServiceClient;
}
public async Task<User> Handle(Query request, CancellationToken cancellationToken)
{
var user = await _graphServiceClient.Me.Request().GetAsync();
return user;
}
}
}
}
希望我在这里走在正确的轨道上,但如果我不是,请告诉我。
对,所以这是我的一个简单疏忽。
根据@franklores,您需要在启动 class 服务中注册 Microsoft Graph:
services.AddMicrosoftIdentityWebApiAuthentication(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddMicrosoftGraph(Configuration.GetSection("DownstreamApi"))
.AddInMemoryTokenCaches();
将以下内容添加到 appsettings(范围可能不同):
"DownstreamAPI": {
"BaseUrl": "https://graph.microsoft.com/v1.0",
"Scopes": "user.read"
},
并确保安装Microsoft.Identity.Web.MicrosoftGraph
以启用AddMicrosoftGraph()
功能。