标签: scrutor

为什么我会收到此 InvalidOperationException:无法解析类型“Microsoft.AspNetCore.Http.RequestDelegate”的服务?

我刚刚将 ASP.NET Core WebApi 项目从 .NET Core 2.2升级到3.1

我已经修复了所有编译时错误,升级了 Nuget 包,现在可以运行该应用程序。

但是,当我调用Build()my时IHostBuilder,出现以下异常:

InvalidOperationException:尝试激活“MyProject.Api.Middleware.ExceptionHandlerMiddleware”时无法解析类型“Microsoft.AspNetCore.Http.RequestDelegate”的服务。

无效操作异常

它所指的中间件是非常标准的。

ExceptionHandlerMiddleware.cs

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()

程序.cs

public class Program
{
    public static void Main(string[] args)
    { …
Run Code Online (Sandbox Code Playgroud)

c# .net-core asp.net-core scrutor asp.net-core-3.1

10
推荐指数
3
解决办法
9325
查看次数

向 Scrutor 注册开放通用装饰器

我有一个标准的 .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)

c# dependency-injection decorator scrutor

4
推荐指数
1
解决办法
2746
查看次数

在 ASP.NET Core 的 Application Insights 中填充用户 ID 字段

我希望能够使用我的真实用户名数据填充 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

3
推荐指数
1
解决办法
1299
查看次数

如何在 Scrutor 中注册组件上的所有接口(类似 StructureMap)

如何在带有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

3
推荐指数
1
解决办法
4958
查看次数

从注入 DI 的 IHttpClientFactory 获取名称 HttpClient

在 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)

c# dependency-injection scrutor blazor-webassembly

1
推荐指数
1
解决办法
5227
查看次数