ipjohnson / Grace.DependencyInjection.Extensions

Grace Extensions for ASP.Net Core
19 stars 7 forks source link

Grace.DependencyInjection.Exceptions.RecursiveLocateException with Decoration in HostBuilder #25

Closed Mike-E-angelo closed 4 years ago

Mike-E-angelo commented 4 years ago

Hello there,

I am exploring the use of this library, but am having some difficulty with decorations during the configuration of a host builder.

Here is the xUnit test I am developing:

[Fact]
async Task Grace()
{
    var host = new HostBuilder().UseGrace()
                                .ConfigureServices(x => x.AddSingleton("Hello World!"))
                                .ConfigureContainer<IInjectionScope>(x => x.Configure(y => y.ExportDecorator<string>(z => $"Decorated: {z}")))
                                .Build();
    await host.StartAsync();

    host.Services.GetRequiredService<string>().Should().Be("Decorated: Hello World!");
}

When using the above, I get a rather lengthy error:


Grace.DependencyInjection.Exceptions.RecursiveLocateException : Recursive object graph detected
1 Importing System.String 
2 Importing System.String 
3 Importing System.String 
4 Importing System.String 
5 Importing System.String 
6 Importing System.String 
7 Importing System.String 
8 Importing System.String 
9 Importing System.String 
10 Importing System.String 
11 Importing System.String 
12 Importing System.String 
13 Importing System.String 
14 Importing System.String 
15 Importing System.String 
16 Importing System.String 
17 Importing System.String 
18 Importing System.String 
19 Importing System.String 
20 Importing System.String 

Dropped 60 entries

81 Importing System.String 
82 Importing System.String 
83 Importing System.String 
84 Importing System.String 
85 Importing System.String 
86 Importing System.String 
87 Importing System.String 
88 Importing System.String 
89 Importing System.String 
90 Importing System.String 
91 Importing System.String 
92 Importing System.String 
93 Importing System.String 
94 Importing System.String 
95 Importing System.String 
96 Importing System.String 
97 Importing System.String 
98 Importing System.String 
99 Importing System.String 
100 Importing System.String 

   at Grace.DependencyInjection.Impl.Expressions.ActivationExpressionRequest.NewRequest(Type activationType, IActivationStrategy requestingStrategy, Type injectedType, RequestType requestType, Object info, Boolean maintainPaths, Boolean carryData)
   at Grace.DependencyInjection.Impl.CompiledStrategies.CompiledInitializationDecoratorStrategy`1.InternalGetDecoratorActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
   at Grace.DependencyInjection.Impl.CompiledStrategies.CompiledInitializationDecoratorStrategy`1.GetDecoratorActivationExpression(IInjectionScope scope, IActivationExpressionRequest request, ICompiledLifestyle lifestyle)
   at Grace.DependencyInjection.Impl.Expressions.DecoratorActivationPathNode.GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
   at Grace.DependencyInjection.Impl.Expressions.ActivationExpressionBuilder.CreateDecoratedActivationStrategy(IInjectionScope scope, IActivationExpressionRequest request, ICompiledExportStrategy strategy, List`1 decorators)
   at Grace.DependencyInjection.Impl.Expressions.ActivationExpressionBuilder.DecorateExportStrategy(IInjectionScope scope, IActivationExpressionRequest request, ICompiledExportStrategy strategy)
   at Grace.DependencyInjection.Impl.InstanceStrategies.BaseInstanceExportStrategy.GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
   at Grace.DependencyInjection.Impl.Expressions.ActivationExpressionBuilder.ActivationExpressionForStrategy(IInjectionScope scope, IActivationExpressionRequest request, ICompiledExportStrategy strategy)
   at Grace.DependencyInjection.Impl.Expressions.ActivationExpressionBuilder.GetExpressionFromStrategyCollection(IInjectionScope scope, IActivationExpressionRequest request)
   at Grace.DependencyInjection.Impl.Expressions.ActivationExpressionBuilder.GetActivationExpressionFromStrategies(IInjectionScope scope, IActivationExpressionRequest request)
   at Grace.DependencyInjection.Impl.Expressions.ActivationExpressionBuilder.GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
   at Grace.DependencyInjection.Impl.CompiledStrategies.CompiledInitializationDecoratorStrategy`1.InternalGetDecoratorActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
   at 

... much repeat. 😆

My intent here is to utilize the "built-in" Microsoft.DependencyInjection.Abstractions (AddSingleton, AddTransient, AddScoped, etc) and then use the ConfigureContainer for Grace-specific functionality such as decoration.

FWIW, this approach worked fine when using LightInject, but because it appears that it does some funny business with Func<,> delegates that cannot be turned off, it has forced me to consider alternatives.

Is there a very obvious method call and/or configuration I am overlooking, perhaps?

Thank you for any assistance you can provide and for your efforts into this library. 👍

Mike-E-angelo commented 4 years ago

The other observation of note is that the ExportDecorator method I am using in the above test is a void method, which seems different from all the other fluent-based method calls that I see having to deal with decorator (and pretty much everything else 😆), so perhaps this is not the right method to call.

I did not see any others or equivalents that perform the same registration as I am attempting to do here, nor have I found any documentation around decorations, but will continue to search in the meantime and update here accordingly.

ipjohnson commented 4 years ago

Hi mike

I’ll take a look today. I’m not exactly sure why it’s doing this.

silkfire commented 4 years ago

@Mike-EEE It looks like the generic ExportDecorator method indeed returns void, whereas the non-generic one returns IFluentDecoratorStrategyConfiguration.

https://github.com/ipjohnson/Grace/blob/e6853c7fb3b23a27824b9b2e17ad860b9b4a403b/src/Grace/DependencyInjection/Impl/ExportRegistrationBlock.cs#L529

ipjohnson commented 4 years ago

Good catch, I apparently overlooked the delegate decorator configuration.

Mike-E-angelo commented 4 years ago

Woohoo, happy to "help" yall. 😆

ipjohnson commented 4 years ago

I've committed a fix for this issue and I'll be looking to do a Beta release this weekend with a couple other issues.

I'll update this issue when they are released.

Mike-E-angelo commented 4 years ago

Great! Thank you, @ipjohnson!

ipjohnson commented 4 years ago

Hi @Mike-EEE

I've pushed a beta package to NuGet to address this so you'll need to install Grace.7.1.1-Beta784

Mike-E-angelo commented 4 years ago

Awesome, thank you @ipjohnson! I can confirm that this now works as expected on my side. 👍 I appreciate the quick weekend efforts!

ipjohnson commented 4 years ago

Your welcome any other issues let me know