我刚刚将 ASP.NET Core WebApi 项目从 .NET Core 2.2升级到3.1。
我已经修复了所有编译时错误,升级了 Nuget 包,现在可以运行该应用程序。
但是,当我调用Build()my时IHostBuilder,出现以下异常:
InvalidOperationException:尝试激活“MyProject.Api.Middleware.ExceptionHandlerMiddleware”时无法解析类型“Microsoft.AspNetCore.Http.RequestDelegate”的服务。
它所指的中间件是非常标准的。
public class ExceptionHandlerMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ExceptionHandlerMiddleware> _logger;
public ExceptionHandlerMiddleware(RequestDelegate next, ILogger<ExceptionHandlerMiddleware> logger)
{
_logger = logger;
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
// redacted
}
}
Run Code Online (Sandbox Code Playgroud)
我的应用程序初始化的其余部分是相当标准的,从 2.2 到 3.1 我没有做太多改变(2.2 正在工作)。
我确实从 更改services.AddMvc()为services.AddControllers()。
public class Program
{
public static void Main(string[] args)
{ …Run Code Online (Sandbox Code Playgroud) 我有一个标准的 .Net core Api,想要使用 Open Generic IRepository 并用 DomainEventPublisher 装饰它,以便在持久化后将事件推送到 servicsBus。然而,我很早就使用过 Simple Injector,我是它的忠实粉丝。但现在使用 MediatR 时,我尝试仅使用 .net Core DI 和 Scrutor 包进行装饰来简化 DI。
问题是我收到的错误:“提供的泛型参数数量不等于泛型类型定义的数量。” 尝试在 Startup 中注册装饰器时来自 Scrutor(下面第二行)。
services.AddSingleton(typeof(IRepository<>), typeof(Repository<>));
services.Decorate(typeof(IRepository<>), typeof(DomainEventPublisher<>));
Run Code Online (Sandbox Code Playgroud)
我已经关闭了这些通用类/接口,然后它就可以工作了。但我不擅长这个。我会像以前在 Simpleinjector 中那样以正确的方式注册开放通用装饰器。
有什么建议可能是什么问题吗?
public class Repository<TEntity> : IRepository<TEntity>
{
private readonly CosmosClient _client;
private readonly IDataContext<TEntity> _context;
private readonly Container _container;
public Repository(CosmosClient client, IDataContext<TEntity> context)
{
_client = client;
_context = context ?? throw new ArgumentNullException(nameof(context));
_container = _client.GetContainer(_context.GetDatabase(), _context.GetContainer());
}
public virtual async Task Add(TEntity entity) …Run Code Online (Sandbox Code Playgroud) 我希望能够使用我的真实用户名数据填充 Application Insights 中的用户 ID 字段。这是一个内部应用程序,因此对简单用户名字段的隐私问题没有实际意义。
据我所知,所有在线可用的解决方案都严格适用于 .NET Framework,而不是 .NET Core。
您可以在几个地方找到此解决方案,包括 GitHub 上的一些旧 AI 文档。但是,当我运行它时,我在启动时收到一个错误,表明单例不能接受对作用域对象 IHttpContextAccessor 的依赖,这当然是合乎逻辑的。除非 .NET Core 的 DI 的先前版本允许(我使用的是 2.2),否则我看不出这是如何工作的。
GitHub 上的这个 issue有点说明了问题,但在 AI 团队指出你必须使用单例后,它被关闭了。我尝试了 OP 中的内容和第一个响应的变体,当代码运行时,AI 上的用户 ID 字段继续充满乱码数据。
有没有办法让 AI 中的 User Id 字段填充一些对来自 ASP.NET Core 应用程序的服务器请求有用的东西?
在看到下面的答案后,我的代码应该可以正常工作,我回过头来意识到异常消息没有特别提到 IHttpContextAccessor:
System.InvalidOperationException: '不能从单例'Microsoft.Extensions.Options.IConfigureOptions`1[Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration]'使用范围服务'Microsoft.ApplicationInsights.Extensibility.ITelemetryInitializer'。'
现在,我的代码看起来与下面@PeterBons 的答案几乎相同,因此从表面上看,此异常毫无意义。 TelemetryConfiguration没有事件出现在我的代码中。但后来我想起我正在使用 Scrutor 在 Startup 中懒惰地进行 DI 注册:
services.Scan(scan => scan
.FromAssembliesOf(typeof(Startup), typeof(MyDbContext))
.AddClasses()
.AsSelfWithInterfaces().WithScopedLifetime());
Run Code Online (Sandbox Code Playgroud)
我认为问题是我需要将我的 ITelemetryInitializer 注册为 Singleton,而这段代码无意中将其取消或重新注册为作用域。所以我把最后两行改为:
.AddClasses(f => f.Where(t => t != typeof(RealUserAIProvider)))
.AsSelfWithInterfaces().WithScopedLifetime()); …Run Code Online (Sandbox Code Playgroud) azure-application-insights asp.net-core asp.net-core-2.2 scrutor
如何在带有scan扩展的程序集中注册所有接口,而无需在 ASP.NET Core 2 中将所有接口分开写入?
在结构图中:
Scan(_ =>
{
// Declare which assemblies to scan
_.Assembly("StructureMap.Testing");
});
Run Code Online (Sandbox Code Playgroud)
在巡查员中:
collection.Scan(scan => scan
// We start out with all types in the assembly of ITransientService
.FromAssemblyOf<ITransientService>()
// AddClasses starts out with all public, non-abstract types in this
// assembly. These types are then filtered by the delegate passed to the
// method. In this case, we filter out only the classes that are assignable
// to ITransientService.
.AddClasses(classes => classes.AssignableTo<ITransientService>()) …Run Code Online (Sandbox Code Playgroud) dependency-injection inversion-of-control .net-core asp.net-core scrutor
在 Blazor 中,我设置了两个 HttpClient。一份用于我的 API,一份用于 MS Graph API。Graph API 是新的,它迫使我找到一种将命名的 httpclient 注入到我的服务中的方法。
这是Main中的所有代码
public class Program
{
public static async Task Main(string[] args)
{
var b = WebAssemblyHostBuilder.CreateDefault(args);
b.RootComponents.Add<App>("app");
var samsonApiUrl = new Uri(b.HostEnvironment.BaseAddress + "api/");
b.Services.AddHttpClient("SamsonApi",client =>
{
client.BaseAddress = samsonApiUrl;
// add jwt token to header
// add user agent to header
}).AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
b.Services.AddTransient<GraphCustomAuthorizationMessageHandler>();
b.Services.AddHttpClient<GraphHttpClientService>("GraphAPI",
client => client.BaseAddress = new Uri("https://graph.microsoft.com/"))
.AddHttpMessageHandler<GraphCustomAuthorizationMessageHandler>();
b.Services.AddScoped(provider => provider.GetService<IHttpClientFactory>().CreateClient("SamsonApi"));
b.Services.AddScoped(provider => provider.GetService<IHttpClientFactory>().CreateClient("GraphAPI"));
b.Services.AddMsalAuthentication<RemoteAuthenticationState, CustomUserAccount>(options =>
{
b.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
options.ProviderOptions.DefaultAccessTokenScopes.Add("1c8d4e31-97dd-4a54-8c2b-0d81e4356bf9/API.Access");
options.UserOptions.RoleClaim = "role"; …Run Code Online (Sandbox Code Playgroud)