Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.1.0-preview-531: Exception when building expressions #76

Closed
schuettecarsten opened this issue Apr 8, 2020 · 10 comments
Closed

3.1.0-preview-531: Exception when building expressions #76

schuettecarsten opened this issue Apr 8, 2020 · 10 comments
Assignees
Labels
Milestone

Comments

@schuettecarsten
Copy link
Contributor

I get the following exception when upgrading one of my projects to Stashbox preview version 3.1.0-preview-531. The same code worked fine using 2.8.9 before. Exception message and callstack are: Auf die Variable "" vom Typ "Neusta.Shared.Services.UnitOfWork.IServiceContextWithUnitOfWork" wird vom Bereich "" verwiesen, sie ist jedoch nicht definiert.

   at System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpression node, VariableStorageKind storage)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterExpression node)
   at System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitNew(NewExpression node)
   at System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitArguments(IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitMethodCall(MethodCallExpression node)
   at System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
   at System.Linq.Expressions.ExpressionExtensions.CompileDelegate(Expression expression, ResolutionContext resolutionContext, ContainerConfiguration containerConfiguration)
   at Stashbox.Lifetime.ScopedLifetime.GetExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, IObjectBuilder objectBuilder, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.Registration.ServiceRegistration.ConstructExpression(IContainerContext containerContext, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.Registration.ServiceRegistration.GetExpression(IContainerContext containerContext, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.Resolution.ResolutionStrategy.BuildResolutionExpression(IContainerContext containerContext, ResolutionContext resolutionContext, TypeInformation typeInformation, IEnumerable`1 injectionParameters, Boolean forceSkipUnknownTypeCheck)
   at Stashbox.BuildUp.Expressions.MethodExpressionBuilder.TryBuildMethod(MethodBase method, RegistrationContext registrationContext, ResolutionContext resolutionContext, IContainerContext containerContext, TypeInformation& failedParameter, Expression[]& parameterExpressions, Boolean skipUknownResolution)
   at Stashbox.BuildUp.Expressions.MethodExpressionBuilder.SelectConstructor(IContainerContext containerContext, RegistrationContext registrationContext, ResolutionContext resolutionContext, ConstructorInfo[] constructors, Expression[]& parameterExpressions)
   at Stashbox.BuildUp.Expressions.ExpressionBuilder.CreateInitExpression(IContainerContext containerContext, RegistrationContext registrationContext, ResolutionContext resolutionContext, ConstructorInfo[] constructors)
   at Stashbox.BuildUp.Expressions.ExpressionBuilder.ConstructExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type serviceType)
   at Stashbox.BuildUp.ObjectBuilders.DefaultObjectBuilder.PrepareExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.BuildUp.ObjectBuilders.DefaultObjectBuilder.GetExpressionInternal(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.BuildUp.ObjectBuilderBase.BuildDisposalTrackingAndFinalizerExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.BuildUp.ObjectBuilderBase.GetExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.Lifetime.ScopedLifetime.GetExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, IObjectBuilder objectBuilder, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.Registration.ServiceRegistration.ConstructExpression(IContainerContext containerContext, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.Registration.ServiceRegistration.GetExpression(IContainerContext containerContext, ResolutionContext resolutionContext, Type resolveType)
   at Stashbox.ResolutionScope.Activate(ResolutionContext resolutionContext, Type type, Object name)
   at Stashbox.ResolutionScope.Resolve(Type typeFrom, Boolean nullResultAllowed, Object[] dependencyOverrides)
   at Stashbox.DependencyResolverExtensions.Resolve[TKey](IDependencyResolver resolver, Boolean nullResultAllowed, Object[] dependencyOverrides)
   at Neusta.Shared.ObjectProvider.Stashbox.Service.StashboxScope.GetInstance[TService](Object[] dependencyOverrides) in D:\Projekte\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Service\StashboxScope.cs:line 117
@z4kn4fein
Copy link
Owner

Thanks for reporting this issue!
This looks bad, I did a major refactor in 3.1 but it seems some cases are not covered yet, I'm going to dig into this, in the meantime could you please give me some details about the context? The type requested when this error occurred, the lifetimes of the dependencies or a small sample project where I can reproduce, every detail could help, thanks in advance!

@z4kn4fein z4kn4fein added the bug label Apr 8, 2020
@z4kn4fein z4kn4fein added this to the v3.1.0 milestone Apr 8, 2020
@z4kn4fein z4kn4fein self-assigned this Apr 8, 2020
@schuettecarsten
Copy link
Contributor Author

schuettecarsten commented Apr 8, 2020

The type requested is registered as plain class, no interfaces, and without lifetime. It is requested using Resolve<BillingPeriodService>(false, null); from a named scope. I will try to reproduce in a small test project or - maybe it's a good idea - checkout the stashbox source code and try to get any details from the debugger.

	[UsedImplicitly]
	public class BillingPeriodService : BaseServiceWithUnitOfWork
	{
		public BillingPeriodService(IServiceContextWithUnitOfWork serviceContext, AccountService accountService)
			: base(serviceContext)
		{
	[UsedImplicitly]
	public class AccountService : BaseServiceWithUnitOfWork
	{
		public AccountService(IServiceContextWithUnitOfWork serviceContext)
			: base(serviceContext)
		{
	[UsedImplicitly]
	public class ServiceContextWithUnitOfWork : ServiceContext, IServiceContextWithUnitOfWork
	{
		public ServiceContextWithUnitOfWork(IObjectProvider objectProvider)
			: base(objectProvider)
		{

Please note that the IObjectProvider is the same interface from my previous ticket, where resolving it to the factory does not work in my project.

@z4kn4fein
Copy link
Owner

Thanks for the context! I'm going to check what could be the issue here.

@schuettecarsten
Copy link
Contributor Author

schuettecarsten commented Apr 8, 2020

I just figured out that it works with preview-519, but fails with preview-520. Maybe this helps, unfortunately, I cannot see which changes were made between these two preview releases.

@z4kn4fein
Copy link
Owner

Yep, the changes between those are related to the scoped resolution, thanks for the info!

@schuettecarsten
Copy link
Contributor Author

schuettecarsten commented Apr 8, 2020

This is the expression that fails to compile (from latest master):

.Block(AccountService $var1) {
    .Call $scope.CheckRuntimeCircularDependencyBarrier(
        459,
        .Constant<System.RuntimeType>(AccountService));
    $var1 = .Call $scope.AddDisposableTracking(.New AccountService($var2)
    );
    .Call $scope.ResetRuntimeCircularDependencyBarrier(459);
    $var1
}

Just another idea, it's using a block here, starts a check and resets a check. Isn't a try/finally block a good idea here, to make sure that everything stays intact when the constructor itself fails with an exception?

@z4kn4fein
Copy link
Owner

Thanks! I found the root cause of this issue, I'll let you know when the fix is ready.

z4kn4fein added a commit that referenced this issue Apr 17, 2020
@schuettecarsten
Copy link
Contributor Author

schuettecarsten commented Apr 19, 2020

Just for your information, it still does not work after commit c20c4c5

System.InvalidOperationException
  HResult=0x80131509
  Message=Auf die Variable "" vom Typ "Neusta.Shared.Services.UnitOfWork.IServiceContextWithUnitOfWork" wird vom Bereich "" verwiesen, sie ist jedoch nicht definiert.
  Source=System.Core
  StackTrace:
   at System.Linq.Expressions.Compiler.VariableBinder.Reference(ParameterExpression node, VariableStorageKind storage)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(ParameterExpression node)
   at System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
   at System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.Visit(ReadOnlyCollection`1 nodes)
   at System.Linq.Expressions.Compiler.VariableBinder.VisitLambda[T](Expression`1 node)
   at System.Linq.Expressions.Compiler.VariableBinder.Visit(Expression node)
   at System.Linq.Expressions.Compiler.LambdaCompiler.Compile(LambdaExpression lambda, DebugInfoGenerator debugInfoGenerator)
   at System.Linq.Expressions.Expression`1.Compile()
   at System.Linq.Expressions.ExpressionExtensions.CompileDelegate(Expression expression, ResolutionContext resolutionContext, ContainerConfiguration containerConfiguration) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Extensions\ExpressionExtensions.cs:line 47
   at Stashbox.Lifetime.SingletonLifetime.GetExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, IObjectBuilder objectBuilder, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Lifetime\SingletonLifetime.cs:line 29
   at Stashbox.Registration.ServiceRegistration.ConstructExpression(IContainerContext containerContext, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Registration\ServiceRegistration.cs:line 124
   at Stashbox.Registration.ServiceRegistration.GetExpression(IContainerContext containerContext, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Registration\ServiceRegistration.cs:line 104
   at Stashbox.Resolution.ResolutionStrategy.BuildResolutionExpression(IContainerContext containerContext, ResolutionContext resolutionContext, TypeInformation typeInformation, IEnumerable`1 injectionParameters, Boolean forceSkipUnknownTypeCheck) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Resolution\ResolutionStrategy.cs:line 76
   at Stashbox.BuildUp.Expressions.MethodExpressionBuilder.TryBuildMethod(MethodBase method, RegistrationContext registrationContext, ResolutionContext resolutionContext, IContainerContext containerContext, TypeInformation& failedParameter, Expression[]& parameterExpressions, Boolean skipUknownResolution) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\BuildUp\Expressions\MethodExpressionBuilder.cs:line 120
   at Stashbox.BuildUp.Expressions.MethodExpressionBuilder.SelectConstructor(IContainerContext containerContext, RegistrationContext registrationContext, ResolutionContext resolutionContext, ConstructorInfo[] constructors, Expression[]& parameterExpressions) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\BuildUp\Expressions\MethodExpressionBuilder.cs:line 52
   at Stashbox.BuildUp.Expressions.ExpressionBuilder.CreateInitExpression(IContainerContext containerContext, RegistrationContext registrationContext, ResolutionContext resolutionContext, ConstructorInfo[] constructors) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\BuildUp\Expressions\ExpressionBuilder.cs:line 204
   at Stashbox.BuildUp.Expressions.ExpressionBuilder.ConstructExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type serviceType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\BuildUp\Expressions\ExpressionBuilder.cs:line 110
   at Stashbox.BuildUp.ObjectBuilders.DefaultObjectBuilder.PrepareExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\BuildUp\ObjectBuilders\DefaultObjectBuilder.cs:line 38
   at Stashbox.BuildUp.ObjectBuilders.DefaultObjectBuilder.GetExpressionInternal(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\BuildUp\ObjectBuilders\DefaultObjectBuilder.cs:line 30
   at Stashbox.BuildUp.ObjectBuilderBase.BuildDisposalTrackingAndFinalizerExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\BuildUp\ObjectBuilderBase.cs:line 52
   at Stashbox.BuildUp.ObjectBuilderBase.GetExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\BuildUp\ObjectBuilderBase.cs:line 21
   at Stashbox.Lifetime.LifetimeBase.GetExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, IObjectBuilder objectBuilder, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Lifetime\LifetimeBase.cs:line 16
   at Stashbox.Lifetime.ScopedLifetimeBase.GetFactoryExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, IObjectBuilder objectBuilder, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Lifetime\ScopedLifetimeBase.cs:line 39
   at Stashbox.Lifetime.ScopedLifetime.GetExpression(IContainerContext containerContext, IServiceRegistration serviceRegistration, IObjectBuilder objectBuilder, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Lifetime\ScopedLifetime.cs:line 25
   at Stashbox.Registration.ServiceRegistration.ConstructExpression(IContainerContext containerContext, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Registration\ServiceRegistration.cs:line 124
   at Stashbox.Registration.ServiceRegistration.GetExpression(IContainerContext containerContext, ResolutionContext resolutionContext, Type resolveType) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Registration\ServiceRegistration.cs:line 104
   at Stashbox.ResolutionScope.Activate(ResolutionContext resolutionContext, Type type, Object name) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\ResolutionScope.cs:line 292
   at Stashbox.ResolutionScope.Resolve(Type typeFrom, Boolean nullResultAllowed, Object[] dependencyOverrides) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\ResolutionScope.cs:line 86
   at Stashbox.DependencyResolverExtensions.Resolve[TKey](IDependencyResolver resolver, Boolean nullResultAllowed, Object[] dependencyOverrides) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Stashbox\src\Resolution\Extensions\DependencyResolverExtensions.cs:line 20
   at Neusta.Shared.ObjectProvider.Stashbox.Service.StashboxScope.GetInstance[TService](Object[] dependencyOverrides) in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Stashbox\Service\StashboxScope.cs:line 117
   at Neusta.Shared.ObjectProvider.Utils.ScopeHelper.<ExecuteServiceInScopeAsync>d__6`1.MoveNext() in D:\Projekte\Azure\CloudManagementTool\Source\SharedLibrary\Neusta.Shared.ObjectProvider.Abstractions\Utils\ScopeHelper.cs:line 126
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at CloudManagementTool.InteractiveWorker.<RunDebugAsync>d__2.MoveNext() in D:\Projekte\Azure\CloudManagementTool\Source\CloudManagementTool\CloudManagementTool\InteractiveWorker.cs:line 50

  This exception was originally thrown at this call stack:
    System.Linq.Expressions.Compiler.VariableBinder.Reference(System.Linq.Expressions.ParameterExpression, System.Linq.Expressions.Compiler.VariableStorageKind)
    System.Linq.Expressions.Compiler.VariableBinder.VisitParameter(System.Linq.Expressions.ParameterExpression)
    System.Linq.Expressions.Compiler.VariableBinder.Visit(System.Linq.Expressions.Expression)
    System.Linq.Expressions.ExpressionVisitor.VisitBinary(System.Linq.Expressions.BinaryExpression)
    System.Linq.Expressions.Compiler.VariableBinder.Visit(System.Linq.Expressions.Expression)
    System.Linq.Expressions.ExpressionVisitor.Visit(System.Collections.ObjectModel.ReadOnlyCollection<System.Linq.Expressions.Expression>)
    System.Linq.Expressions.Compiler.VariableBinder.VisitLambda<T>(System.Linq.Expressions.Expression<T>)
    System.Linq.Expressions.Compiler.VariableBinder.Visit(System.Linq.Expressions.Expression)
    System.Linq.Expressions.Compiler.LambdaCompiler.Compile(System.Linq.Expressions.LambdaExpression, System.Runtime.CompilerServices.DebugInfoGenerator)
    System.Linq.Expressions.Expression<TDelegate>.Compile()
    ...
    [Call Stack Truncated]

z4kn4fein added a commit that referenced this issue Apr 22, 2020
@z4kn4fein
Copy link
Owner

Thanks for the fast feedback! I'm aware of this, the previous commit was only the first part of the whole fix, unfortunately, it'll take a bit more time, some skeletons fell out during the refactor, so I have to do some more investigation about what parts are also affected. This is another pack of the fix, could you please run a new test with it? Thanks! And also for your patience!

@schuettecarsten
Copy link
Contributor Author

Thank you for the fix - it works now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants