Closed ilya-malakhovsky closed 9 months ago
Can you supply me with a full stack trace of the exception?
Unhandled exception during request [500] [ActivationException] :
Cannot access a disposed object. Object name: 'SimpleInjector.Scope'. at
SimpleInjector.InstanceProducer.GetInstance() at
SimpleInjector.Container.GetInstance[TService]() at
MyProject.ServiceConfig.<>c__DisplayClass11_0.<Config>g__Create|1() at
lambda_method(Closure ) at
SimpleInjector.InstanceProducer.GetInstance() at
SimpleInjector.Container.GetInstance[TService]() at
MyProject.Services.Account.CustomRoleProvider.GetRolesForUser(String username)
MyProject.MiniProfilerModule.onEndRequest(Object sender, EventArgs e) at
System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at
System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) at
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
[ObjectDisposedException] : `Cannot access a disposed object. Object name: 'SimpleInjector.Scope'.` at
SimpleInjector.Scope.ThrowObjectDisposedException() at
SimpleInjector.Scope.GetInstanceInternal(ScopedRegistration registration) at
SimpleInjector.Scope.GetInstance[TImplementation](ScopedRegistration registration, Scope scope) at
SimpleInjector.Advanced.Internal.LazyScopedRegistration`1.GetInstance(Scope scope) at
lambda_method(Closure ) at
SimpleInjector.InstanceProducer.GetInstance()
Registration is done like this:
c.Register<Tracker>(Lifestyle.Scoped);
c.Register<IUnitOfWork>(Create);
Create
is a method from my previous message
What you're dealing with is a a combination of corner cases:
Having Simple Injector correctly return null
from its GetCurrentScope
, however, will unlikely fix your issue, because you want to resolve an instance from a scope. It being null
will still not allow you to resolve scoped instances.
Unfortunately, there's little I can do here, because:
I would, therefore, suggest a different solution. Here are some suggestions:
I hope this helps
thanks a lot for your explanation - I'll try to think on alternative ways.
return null from its GetCurrentScope, however, will unlikely fix your issue, because you want to resolve an instance from a scope. It being null will still not allow you to resolve scoped instances
Actually it would help as only Tracker
is registered as Scoped and can't be resolved but I'm fine not to track at that moment during this edge case. I.e. UnitOfWork
that is required during the work of the profiler is resolved fine since it's registered as Transient.
I struggled with the weird request lifestyle model of those web frameworks years ago, which is one of the many reasons I moved to design that I found easier to reason about, which is the use of an ICommandHandler<T>
abstraction, which I described here. This allows me to apply cross-cutting concerns like your tracker logic on the boundaries of executed commands.
Changing your application to a design as described in that article might be quite an undertaking, and might not be feasible for you at the moment, but it might give you some inspiration on ways of looking at this from a different angle.
Hi!
I'm using
SimpleInjector
withTransient
andSingleton
scopes mostly for my web-application (for historical reasons). Now I want to add some monitoring at the end of each web-request to check if state of objects is correct (basically I'm checking thatDBContext
doesn't contain any unsaved changes)For this I've created a
Tracker
class :Tracker
registered asScoped
in the containerIUnitOfWork
I've injected resolving ofTracker
from the container and adding createdIUnitOfWork
to tracked list inside theTracker
Scope.WhenScopeEnds
Tracker
checks all registeredIUnitOfWork
s(I can't change the Lifetime of
IUnitOfWork
registration)Factory method for
IUnitOfWork
looks like this if simplified:My problem is that
IUnitOfWork
can be resolved at any stage of the application (I can't change this) including when there's no web-request yet (I'm checking this asLifestyle.Scoped.GetCurrentScope(container) != null
) and when the request has just ended (checks onHttpApplication.EndRequest
).In the latter case I sometimes get:
[ObjectDisposedException] : `Cannot access a disposed object. Object name: 'SimpleInjector.Scope'
Is there a way to know that the
Scope
was already disposed? In the debug I can see thatGetCurrentScope
returns me a disposedScope
(I see that it' was disposed via it's internal properties). I would expect it to be null as technically we are out of scope already.