JasperFx / lamar

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

Application Insights profiler (AddServiceProfiler) fails when using Lamar #352

Open andreas-valtech opened 1 year ago

andreas-valtech commented 1 year ago

In the method AddServiceProfilerfrom the package Microsoft.ApplicationInsights.Profiler.AspNetCore a dependecy on a Func<int> is used which crashes Lamar if no such registration is found. The built in IoC container just ignores the parameter since it has a default value.

The failure happens in ProcessInfoCPUMetricsProvidersince it cant resolve the Func<int> getProcessorCount dependency:

public ProcessInfoCPUMetricsProvider(
      IProcessProvider processProvider,
      ILogger<ProcessInfoCPUMetricsProvider> logger,
      (DateTimeOffset, TimeSpan)? initialSnap = null,
      Func<int> getProcessorCount = null)

I have added a workaround in my Startup.cs which works but is a bit sketchy:

services.AddTransient((_) => new Func<int>(() => System.Environment.ProcessorCount));
services.AddApplicationInsightsTelemetry();
services.AddServiceProfiler();

Using Lamar.Microsoft.DependencyInjection version 8.0.1.

The stack trace I get without the workaround above is:


fail: Microsoft.ApplicationInsights.Profiler.AspNetCore.ServiceProfilerStartupFilter[0]
      Unexpected error.
      System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
       ---> Lamar.IoC.LamarMissingRegistrationException: No service registrations exist or can be derived for int
         at Lamar.IoC.Scope.GetInstance(Type serviceType)
         at Lamar.IoC.Scope.GetInstance[T]()
         at Microsoft.ServiceProfiler.Orchestration.MetricsProviders.ProcessInfoCPUMetricsProvider..ctor(IProcessProvider processProvider, ILogger`1 logger, Nullable`1 initialSnap, Func`1 getProcessorCount)
         --- End of inner exception stack trace ---
         at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
         at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
         at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
         at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
         at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.<>c__DisplayClass18_0.<quickResolve>b__0(CtorArg x)
         at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
         at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.<>c__DisplayClass18_0.<quickResolve>b__0(CtorArg x)
         at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
         at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.<>c__DisplayClass18_0.<quickResolve>b__0(CtorArg x)
         at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
         at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.<>c__DisplayClass15_0.<ToResolver>b__0(Scope s)
         at Lamar.ServiceGraph.<>c__DisplayClass48_0.<FindResolver>b__0(Scope s)
         at Lamar.IoC.Scope.GetInstance(Type serviceType)
         at Lamar.Container.Microsoft.Extensions.DependencyInjection.ISupportRequiredService.GetRequiredService(Type serviceType)
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
         at Microsoft.Extensions.DependencyInjection.ServiceCollectionBuilder.<>c.<Build>b__0_5(IServiceProvider p)
         at Lamar.IoC.Resolvers.SingletonLambdaResolver`2.Build(Scope scope)
         at Lamar.IoC.Resolvers.SingletonResolver`1.Resolve(Scope scope)
         at Lamar.IoC.Instances.LambdaInstance`2.Resolve(Scope scope)
         at Lamar.IoC.Instances.Instance.QuickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.<>c__DisplayClass18_0.<quickResolve>b__0(CtorArg x)
         at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
         at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.<>c__DisplayClass18_0.<quickResolve>b__0(CtorArg x)
         at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
         at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope)
         at Lamar.IoC.Instances.ConstructorInstance.<>c__DisplayClass15_0.<ToResolver>b__0(Scope s)
         at Lamar.ServiceGraph.<>c__DisplayClass48_0.<FindResolver>b__0(Scope s)
         at Lamar.IoC.Scope.GetInstance(Type serviceType)
         at Lamar.Container.Microsoft.Extensions.DependencyInjection.ISupportRequiredService.GetRequiredService(Type serviceType)
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
         at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
         at Microsoft.ApplicationInsights.Profiler.AspNetCore.ServiceProfilerStartupFilter.<>c__DisplayClass1_1.<<Configure>b__1>d.MoveNext()
jeremydmiller commented 1 year ago

@andreas-valtech The real issue here being that the optional constructor argument should be ignored? I'll get around to this at some point, but I'd point at foolish design on their part for DI usage.

Drol commented 1 year ago

Big thanks for the workaround @andreas-valtech :-)

I made a bug report before finding this issue. https://github.com/microsoft/ApplicationInsights-Profiler-AspNetCore/issues/181

We will see if they are willing to make a change for the problem.

Drol commented 1 year ago

I get this when profiler trying to upload to Azure. Guess it is not made for other IoC frameworks at all...

Lamar.IoC.LamarMissingRegistrationException: Unknown service registration '%SP_UPLOADER_PATH%' of string at Lamar.IoC.Scope.GetInstance(Type serviceType, String name) at Lamar.IoC.Scope.GetInstance[T](String name) at Lamar.IoC.Lazy.FuncByNameInstance1.<>c__DisplayClass6_0.g__Func|0(String name) at Microsoft.ApplicationInsights.Profiler.Core.UploaderProxy.UploaderLocatorByEnvironmentVariable.GetUploaderFullPath() at Microsoft.ApplicationInsights.Profiler.Core.UploaderProxy.UploadLocatorBase.Locate() at Microsoft.ApplicationInsights.Profiler.Core.UploaderProxy.UploaderPathProvider.GetUploaderFullPath() at Microsoft.ApplicationInsights.Profiler.Core.UploaderProxy.UploaderPathProvider.TryGetUploaderFullPath(String& uploaderFullPath) at Microsoft.ApplicationInsights.Profiler.Core.ServiceProfilerProvider.PostStopProcessAsync(PostStopOptions e, CancellationToken cancellationToken) at Microsoft.ApplicationInsights.Profiler.Core.ServiceProfilerProvider.StopServiceProfilerAsync(IProfilerSource source, CancellationToken cancellationToken) at Microsoft.ApplicationInsights.Profiler.Core.Orchestration.OrchestratorEventPipe.StopProfilingAsync(SchedulingPolicy policy, CancellationToken cancellationToken) at Microsoft.ServiceProfiler.Orchestration.SchedulingPolicy.StartPolicyAsync(CancellationToken cancellationToken)`

andreas-valtech commented 1 year ago

This is now resolved by Microsoft in the above mentioned issue (https://github.com/microsoft/ApplicationInsights-Profiler-AspNetCore/issues/181). I have verified it myself and everything works as expected (without any workarounds in place) in the 2.5.2 release of Microsoft.ApplicationInsights.Profiler.AspNetCore.

This issue can be closed.