Closed schuettecarsten closed 4 years ago
Is this still an issue with the latest pre-release version? A covered issue could have led to this, could you please check again? Thanks!
Yes, the issue is still there with https://github.com/z4kn4fein/stashbox/commit/34d7caf469566106dd790d72e812883eeaf97874
Stashbox.Exceptions.ResolutionFailedException
HResult=0x80131500
Message=Could not resolve type BillingPeriodService.
Constructor Void .ctor(IServiceContextWithUnitOfWork) found with unresolvable parameter: (IServiceContextWithUnitOfWork)serviceContext.
Source=ObjectProvider.Stashbox
StackTrace:
at Stashbox.BuildUp.Expressions.MethodExpressionBuilder.SelectConstructor(IContainerContext containerContext, RegistrationContext registrationContext, ResolutionContext resolutionContext, ConstructorInfo[] constructors, Expression[]& parameterExpressions) in ObjectProvider.Stashbox\src\BuildUp\Expressions\MethodExpressionBuilder.cs:line 80
The full callstack vom Visual Studio debugger:
> ObjectProvider.Stashbox.dll!Stashbox.BuildUp.Expressions.MethodExpressionBuilder.SelectConstructor(Stashbox.IContainerContext containerContext, Stashbox.Registration.RegistrationContext registrationContext, Stashbox.Resolution.ResolutionContext resolutionContext, System.Reflection.ConstructorInfo[] constructors, out System.Linq.Expressions.Expression[] parameterExpressions) Line 79 C#
ObjectProvider.Stashbox.dll!Stashbox.BuildUp.Expressions.ExpressionBuilder.CreateInitExpression(Stashbox.IContainerContext containerContext, Stashbox.Registration.RegistrationContext registrationContext, Stashbox.Resolution.ResolutionContext resolutionContext, System.Reflection.ConstructorInfo[] constructors) Line 204 C#
ObjectProvider.Stashbox.dll!Stashbox.BuildUp.Expressions.ExpressionBuilder.ConstructExpression(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type serviceType) Line 110 C#
ObjectProvider.Stashbox.dll!Stashbox.BuildUp.ObjectBuilders.DefaultObjectBuilder.PrepareExpression(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 38 C#
ObjectProvider.Stashbox.dll!Stashbox.BuildUp.ObjectBuilders.DefaultObjectBuilder.GetExpressionInternal(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 30 C#
ObjectProvider.Stashbox.dll!Stashbox.BuildUp.ObjectBuilderBase.BuildDisposalTrackingAndFinalizerExpression(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 54 C#
ObjectProvider.Stashbox.dll!Stashbox.BuildUp.ObjectBuilderBase.GetExpression(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 23 C#
ObjectProvider.Stashbox.dll!Stashbox.Lifetime.LifetimeDescriptor.GetNewFactoryDelegate(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 106 C#
ObjectProvider.Stashbox.dll!Stashbox.Lifetime.LifetimeDescriptor.GetFactoryDelegate(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 100 C#
ObjectProvider.Stashbox.dll!Stashbox.Lifetime.ScopedLifetime.GetLifetimeAppliedExpression(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 21 C#
ObjectProvider.Stashbox.dll!Stashbox.Lifetime.LifetimeDescriptor.GetExpression(Stashbox.IContainerContext containerContext, Stashbox.Registration.IServiceRegistration serviceRegistration, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 34 C#
ObjectProvider.Stashbox.dll!Stashbox.Registration.ServiceRegistration.GetExpression(Stashbox.IContainerContext containerContext, Stashbox.Resolution.ResolutionContext resolutionContext, System.Type resolveType) Line 100 C#
ObjectProvider.Stashbox.dll!Stashbox.Resolution.ResolutionStrategy.BuildResolutionExpression(Stashbox.IContainerContext containerContext, Stashbox.Resolution.ResolutionContext resolutionContext, Stashbox.Entity.TypeInformation typeInformation, System.Collections.Generic.IEnumerable<Stashbox.Entity.InjectionParameter> injectionParameters, bool forceSkipUnknownTypeCheck) Line 76 C#
ObjectProvider.Stashbox.dll!Stashbox.Resolution.Resolvers.UnknownTypeResolver.GetExpression(Stashbox.IContainerContext containerContext, Stashbox.Resolution.IResolutionStrategy resolutionStrategy, Stashbox.Entity.TypeInformation typeInfo, Stashbox.Resolution.ResolutionContext resolutionContext) Line 23 C#
ObjectProvider.Stashbox.dll!Stashbox.Resolution.ResolutionStrategy.BuildResolutionExpressionUsingResolvers(Stashbox.IContainerContext containerContext, Stashbox.Entity.TypeInformation typeInfo, Stashbox.Resolution.ResolutionContext resolutionContext, bool forceSkipUnknownTypeCheck) Line 106 C#
ObjectProvider.Stashbox.dll!Stashbox.ResolutionScope.Activate(Stashbox.Resolution.ResolutionContext resolutionContext, System.Type type, object name) Line 304 C#
ObjectProvider.Stashbox.dll!Stashbox.ResolutionScope.Resolve(System.Type typeFrom, bool nullResultAllowed, object[] dependencyOverrides) Line 86 C#
ObjectProvider.Stashbox.dll!Stashbox.DependencyResolverExtensions.Resolve<CloudManagementTool.Connector.Azure.PartnerCenter.Services.CspInvoiceNotificationMailService>(Stashbox.IDependencyResolver resolver, bool nullResultAllowed, object[] dependencyOverrides) Line 20 C#
[External Code]
Okay, I'm moving forward to this then, thanks!
Hey, the issue was that the UnknownTypeResolver
was not able to resolve your IServiceContextWithUnitOfWork
because it's an interface type, so it was bypassed by the resolver completely. I turned off this behavior when the configuration delegate for the unknown type resolution is set, so it will be called for the interfaces too. Could you please try the new version? Thanks!
There is a new side effect now.
My code gets an InvalidRegistrationException
when I try to get an "optional" interface value from the container using Resolve<ISomeInterface>(true)
. In this case, it's correct that the UnknownTypeResolver is not able to resolve this type, and it's expected that this could happen - null is allowed here.
Hey, thanks for reporting, that side effect should be covered now, could you check please? Thanks!
This seems to work now, but another issue (not sure if this is caused by the fix): services registered with a scope name and Lifetime.NamedScope or with DefinesScope are not found if you try to resolve them form a different scope, regardless if registered at startup or in UnknownTypeResolver.
I can also see that services that are registrered in Singleton scope are disposed when they were used by a different scoped service when the scope that owns the scoped service is disposed.
Sorry for the late response, thanks for reporting these!
That's a by-design thing, services registered with NamedScope are only picked when you resolve them within the scope that has the matching name. That's kind of a resolution condition also. In what case you consider this as an issue? Should it work differently in your opinion?
Could you give me an example of the Singleton issue? I'm not able to reproduce that. Thanks!
I have several services that are registered as "Singleton". In the current implementation, they all share their dependencies and are registered in the same scope. For example, they all use the same DbContext. So my idea was to register the services into a separate "named scope", to isolate them from each other.
Sorry, i think i wasn't clear with this one, i meant that could you please send me a code example or a sample project where the dispose issue with the singletons are reproducable? I did not find any composition to recreate this kind of issue. Singletons are disposed only by the root scope, and I can't see where could be the behavior changed.
I think my Dispose problem was caused by my very strange tries to register Singletons in a Named Scope, sorry for the confusion. I have changed my code to make sure that the Singleton dependencies are registered with Transient scope instead of Scoped/NamedScope. It seems to work now, if I run into new issues, I will create a new issue here.
Thank you for fixing everything :-)
I try to implement a function that resolves my service registration on demand by using Stashbox'
WithUnknownTypeResolution
feature. Look at the following classes:When I try to resolve
BillingPeriodService
, myUnknownTypeResolution
-function is invoked with a context toBillingPeriodService
. I can check my service descriptors and complete the registration context with correct lifetime and implementation type. After that, I get an exception that the type not be resolved. I would expect that myUnknownTypeResolution
-function is invoked again and again for all required constructor parameters...?