JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
563 stars 118 forks source link

'This service descriptor is keyed. Your service provider may not support keyed services.' #395

Open ElanHasson opened 4 months ago

ElanHasson commented 4 months ago

I found #388, which seems related.

I'm using Aspire preview 3 and targeting .net 8.

I get this error at startup:

System.InvalidOperationException
  HResult=0x80131509
  Message=This service descriptor is keyed. Your service provider may not support keyed services.
  Source=Microsoft.Extensions.DependencyInjection.Abstractions
  StackTrace:
   at Microsoft.Extensions.DependencyInjection.ServiceDescriptor.ThrowKeyedDescriptor()
   at Microsoft.Extensions.DependencyInjection.ServiceDescriptor.get_ImplementationType()
   at Lamar.ServiceGraph.<>c__DisplayClass52_0.<buildClosedGenericType>b__0(ServiceDescriptor x)
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
   at System.Collections.Generic.SparseArrayBuilder`1.ReserveOrAdd(IEnumerable`1 items)
   at System.Linq.Enumerable.Concat2Iterator`1.ToArray()
   at Lamar.ServiceGraph.buildClosedGenericType(Type serviceType, IServiceCollection services)
   at Lamar.ServiceGraph.buildFamilyForInstanceGroup(IServiceCollection services, IGrouping`2 group)
   at Lamar.ServiceGraph.<>c__DisplayClass50_0.<organizeIntoFamilies>b__2(IGrouping`2 group)
   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
   at Lamar.ServiceGraph.organizeIntoFamilies(IServiceCollection services)
   at Lamar.ServiceGraph.Initialize()
   at Lamar.IoC.Scope..ctor(IServiceCollection services)
   at Lamar.Container..ctor(IServiceCollection services)
   at Lamar.Microsoft.DependencyInjection.LamarServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
   at Microsoft.Extensions.Hosting.HostApplicationBuilder.Build()
   at Microsoft.AspNetCore.Builder.WebApplicationBuilder.Build()
   at Program.<<Main>$>d__0.MoveNext() in 

Here are my dependencies:

    <PackageVersion Include="Aspire.Hosting" Version="8.0.0-preview.3.24105.21" />
    <PackageVersion Include="Aspire.Npgsql" Version="8.0.0-preview.3.24105.21" />
    <PackageVersion Include="Marten" Version="6.4.1" />
    <PackageVersion Include="Marten.AspNetCore" Version="6.4.1" />
    <PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="8.0.1" />
    <PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
    <PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
    <PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="8.2.0" />
    <PackageVersion Include="Microsoft.Extensions.ServiceDiscovery" Version="8.0.0-preview.2.23619.3" />
    <PackageVersion Include="Microsoft.Azure.Functions.Worker" Version="1.20.0" />
    <PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
    <PackageVersion Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
    <PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
    <PackageVersion Include="Npgsql.OpenTelemetry" Version="8.0.2" />
    <PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.7.0" />
    <PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.7.0" />
    <PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.7.0" />
    <PackageVersion Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.6.0-beta.3" />
    <PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.7.0" />
    <PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.7.0" />
    <PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
    <PackageVersion Include="WolverineFx" Version="1.17.0" />
    <PackageVersion Include="WolverineFx.FluentValidation" Version="1.17.0" />
    <PackageVersion Include="WolverineFx.Http" Version="1.17.0" />
    <PackageVersion Include="WolverineFx.Http.FluentValidation" Version="1.17.0" />
    <PackageVersion Include="WolverineFx.Http.Marten" Version="1.17.0" />
    <PackageVersion Include="WolverineFx.Marten" Version="1.17.0" />
Abdruggi commented 4 months ago

The problem is caused by Microsoft.Extensions.Http.Resilience 8.2.0. As a temporary workaround, you can downgrade to 8.1.0.

ElanHasson commented 4 months ago

Thanks. I've since updated everything and it has gone away, so not sure where it got fixed as Wolverine is now like 1.18.1 or something.

alexrosenfeld10 commented 4 months ago

I am running into the same. @JasperFx any ideas on the fix here? I can take a stab at it if you point me in the right direction (and it's first time contributor friendly 😄)

psampaio commented 3 months ago

I believe you need to check for "!x.IsKeyedService" in ServiceGraph, when building the closed generics, just before the !x.ImplementationType.IsOpenGeneric() call.

The call probably needs to be something like:

var closed = services.Where(x => x.ServiceType == serviceType && (x.IsKeyedService
        ? !x.KeyedImplementationType.IsOpenGeneric()
        : !x.ImplementationType.IsOpenGeneric()))
    .Select(Instance.For);

However, given the way Microsoft implemented these keyed services, I'm not sure this is just an workaround. That's why I didn't submit a PR, I don't fully understand the potential side effects.

psampaio commented 3 months ago

Added a PR anyway, might serve as a starting point.