I have an autofac module which implements IDisposable. The module is registerd with the containerBuilder.RegisterModule<> method and it gets resolved during container.Build. But: Dispose is not called on the module when container gets disposed.
Is this a bug, or do i miss something?
I have reproduced this with Autofac 4.6.2 and 4.8.1, didn't test other versions between.
Modules are not meant to be disposed. The link between Autofac and disposable components is fulfilled by the ILifetimeScope implementations.
A module is basically a box with a Load method, that gets executed once.
When the Load method completes, you must be done with the module.
So, if you have any resource to be kept alive and disposed afterwards, it should be kept alive (and disposed) in one of the lifetime management options.
So, you could say it's a bug, but I personally think it's just a case of a feature that is not needed for the intended use of the modules (this last phrase is just my personal opinion).
If you care to describe (maybe in another question?) what is the actual problem you're trying to solve with a disposable module, we can discuss that.
Related
I have a naive question, I have read about the flutter dependency injection package get_it, it registers all the instances at start like the service locator design pattern, my question is how it deals with a garbage collector and when it frees the objects? Does it store all the instances in memory at start till app lifeCycle?
To be honest, I know very little about Service locator design pattern otherwise I might have understood this package clearly, Now I need your help on how it works under the hood? what if we need to register an instance at run time with some dynamic data coming from API then how can we do that?
Your help will be appreciated thanks in advance
Per the documentation, you can unregister a previously registered instance as follows:
/// Unregister an [instance] of an object or a factory/singleton by Type [T] or by name [instanceName]
/// if you need to dispose some resources before the reset, you can
/// provide a [disposingFunction]. This function overrides the disposing
/// you might have provided when registering.
void unregister<T>({Object instance,String instanceName, void Function(T) disposingFunction})
Service objects are often need throughout the life of an application, in which case you'll never need to unregister.
I am explicitly declaring my registerations as per web request lifecycle but they are still singletons.
this is a problem because my command handlers depend on an IDbConnection which is also registered per web request.
here is my registration code:
container.Register(
Classes
.FromAssemblyContaining<EcruiterCommands>()
.BasedOn(typeof (ICommandHandler<>))
.WithService.AllInterfaces()
.LifestylePerWebRequest());
I found the issue, the culprit is this line:
.BasedOn(typeof (ICommandHandler<>))
it resets the registration.
Say I am using a service A which is imported in another service B. While B is running normally(ofcourse A is Active), what will happen is service A is uninstalled while service B is still running?
Service A -> Service B
What will be the different scenarios in case I am using ServiceReference, ServiceTracker & DS?
When a service is unpublished in OSGi, an event is sent to all bundles currently using that service to tell them that they should stop using it.
If you are using DS, your unbind method will be called. When it is called, you should make best efforts to stop using the service as soon as possible. But ultimately OSGi is a cooperative system, it cannot force you to release the service. However if you don't then you can cause problems, for example the service publisher will not be fully garbage-collected. You end up sabotaging the dynamics of the OSGi platform, possibly creating memory leaks and so on.
If you are using ServiceTracker then the removedService method will be called, and you need to respond in the same way. But didn't I tell you in the other question not to use ServiceTracker?? ;-)
If you are using ServiceReference then you need to explicitly register a ServiceListener in order to receive these events. This is why you really really shouldn't use this low-level API until you have gained a lot more experience (and once you do have that experience, you won't want to use it anyway!).
First of all: one of the advantages of OSGi is that the behaviour of the framework and standard services are clearly specified. Those specifications can be downloaded from the OSGi Alliance web site, or, if you don't like reading PDFs, ordered for print. The question you are asking is perfectly answered in those specifications.
That said, in summary: when a service is unregistered:
The ServiceReference object remains as it is. However, a call to ServiceReference.getService() will return null. Note that when using ServiceReferences you should release any references to the actual service object as retrieved via getService(), this normally requires some kind of tracking of the service.
For ServiceTracker ServiceTracker.remove is called. This normally results in a call to removedService() on the ServiceTracker or the defined ServiceTrackerCustomizer.
For DS, the defined unbind method for the referenced service is called (if specified). Furthermore, if the cardinality for the used service indicates that the service is mandatory, the using service may also be unregistered, even possibly deactivated or a new instance activated depending on the availability of alternative services and the policy defined for the service.
Is there a way to make Autofac to always resolve types in a new lifetimescope?
ie.
Container.Resolve<MyHandler>().Whatever();
Now i have to do like this:
Container.BeginLifetimeScope().Resolve<MyHandler>().Whatever();
It would be nice to be able to inject MyHandler into a class and know that MyHandler is it own scope.
Autofac does not provide a way to automatically start a new lifetime scope per component resolution.
Creating a lifetime scope is actually a process you need to control very tightly. Lifetime scopes not only help the scoping of component resolution, but also manage the deterministic disposal of components you resolve. From a memory management perspective, you shouldn't just fire up lifetime scopes without also disposing of them when you're done. Failing to dispose your created scopes can very easily cause a memory leak.
This is why you always see BeginLifetimeScope in a using statement or in a very tightly integrated scenario like ASP.NET request lifetime - so you can start a scope at a known spot and be sure to end/dispose of it. Child lifetime scopes are not automatically disposed for you once they're created - it's up to you to do that cleanup.
The Autofac wiki has some good information on lifetime scopes here.
Does the Zend 2 event manager have the ability to fire listeners in classes that are not loaded?
If I understand you correctly, then I believe that you can register listeners using the StaticEventManager (see Event Manager Quick Start).
In this case, you do not need to have an instance of the target class (just the name), but you can register listeners for events (typically methods) on future instances of that target class that may occur.
Of course, in order to be useful, the target class should actually compose an EventManager instance (probably via an events() method, as described on the same Quick Start page) and actually fire the events.
I confess that I am still trying to wrap my own head around the ZF2 EventManager, so if I have totally boned it up here, please feel free to correct me.