Can components be temporarily registered in an Autofac container? - autofac

I'm building a plugin for a 3rd party application and my plugin uses Autofac to wire up various components. The container is built at application startup, but the host application invokes my commands at a later time.
When a command is invoked, the host application provides a few instances of types that it defines and that my components will need to use. I'd like to register these instances in the container so that it can take care of wiring up the components that depend on these instances.
I'm aware that I can use a ContainerBuilder to update an existing container, but I'd like to remove these registrations when the command has completed as these instances will no longer be valid. Is this possible?
Maybe a better approach is to use 2 containers... The command could create a new container to register these instances and other components could be resolved from the application scoped container.
How could I hook up the 2 containers so that resolve calls bubble up to the application scoped container?
Are there any gotchas to be aware of with this approach? I imagine there may be component lifetime issues...
Edit: Now I've done a bit more research and testing and and it turns out I can just use the BeginLifetimeScope(Action<ContainerBuilder>) overload to register the host application provided instances for the nested lifetime only. For some reason I thought that adding registrations to the nested lifetime would result in them being added to the root container but that doesn't seem to be the case.

As noted in my edit above, it turns out that BeginLifetimeScope(Action<ContainerBuilder>) is exactly what I need. For some reason I thought that adding registrations to the nested lifetime would result in them being added to the root container and therefore being resolvable after the nested lifetime scope ends, but that doesn't seem to be the case.

Related

Autofac- externally owned container?

I'm using an Autofac container for the entire lifetime of my application, but I want to dispose the components myself.
I.E if I have builder.RegisterType<SomeType>(), I don't want the container to keep references of SomeType which will keep those alive even if not referenced anywhere else (if RegisterInstance is used OTOH, then of course the container must keep a reference to the singleton).
I can see that I can do builder.RegisterType<SomeType>().ExternallyOwned() which solves my problem for one type, but I don't want to write it for every type, and more importantly I also use builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); which doesn't give me the option of using ExternallyOwned.
Is there a way to specify "ExternallyOwned" for the entire container? Or, to put it another way, tell the container to disable the entire dispose feature and not keep references for objects it doesn't need?
There is not a way to disable container disposal services. You might try to hook in with something like the logging module but I could see that not working 100% and missing edge cases of you're not careful.
Automatic tracking and disposal is a pretty common container feature. I'd recommend instead of fighting it you refactor your code to embrace it. It'll make life a lot easier.

Hit REST end point on startup - weblogic + ATG

I have a rest endpoint which would start the scheduler of loading a XML to memory. Whenever I hit that rest endpoint, it loads the XML in memory and would return the XML after its ready (would take 10 - 15 seconds). When the same endpoint is accessed again, it would return the cached XML. Everything works fine but for now I have to manually hit the endpoint for the scheduler to start. Is there a way to hit the endpoint automatically via a simple code in startup? Or is there any other solution for this?
Normally, a component in the Nucleus is instantiated at first access, not at system start-up.
The way to have anything done at start-up in ATG is to create your component, and then to add its nucleus path to the list of initial services in the /Initial component (or from one of the many other Initial components changed off of it)
The component should be globally scoped. Because /Initial is instantiated at start-up, the services it references will also be instantiated as dependencies.
If your component is a POJO, then the no argument constructor will be invoked on component start-up, then the setX method will be called for each property with a value defined in its properties file.
If your component is extended from Generic Service, then additionally, beforeSet and afterSet methods will be called, before and after the set methods are invoked, if they exist, and finally doStartUp will be called.
This is all part of the fundamental lifecycle of components that the Nucleus manages.
This gives you a number of hooks with which to invoke your custom code.
Now, in your question, you ask how to call a REST endpoint at start-up. However, I believe what you actually want to ask is how to ensure that a particular piece of code gets executed at system start-up. A REST endpoint is how you are triggering it today, manually, from outside the Nucleus. But that does not mean that it must call a REST end point if it is to be automatically called at start up.
The easiest way to achieve what you want is
define a class that extends GenericService
override the doStartUp method
put the code you want to execute in this method, or invoke the code on another component from here
define a globally scoped component for the class
Add the component to the initialServices property of the Initial component
Restart the server and check that your code is being called at start-up. Put some debug statements in, and switch debug logging on in your layer.
Note, you may actually also want to think about whether you really need to invoke your code at system start-up. Anything in initial services adds to the start time of the server. Depending on your requirements, it may be better to do it on first access of your application service rather than at server start-up.

Creation and Deletion of NServicebus subscriptions upon Starting and Stopping the bus

The design brief for my project includes the following:
Be able to spin up new instances of Windows Services at will and attach random message handlers to each for the purpose of logically grouping the handlers along service boundary lines (or any other arbitrary reason to group handlers).
The design we've chosen is to encapsulate a given message TYPE and all of it's handlers into a single assembly (DLL). I am trying to generate subscriptions when the host starts and remove them from Raven when the host stops.
I have success in their creation implementing the IWantToRunWhenBusStartsAndStops interface within a particular message TYPE assembly. The IWantToRunWhenBusStartsAndStops.Start() fires and I add the proper subscription there.
The removal is the issue I am trying to solve. The IWantToRunWhenBusStartsAndStops.Stop() method is only invoked when a control-break is issued manually.
Is there a different interface I should be implementing or a different approach to the issue I should take??
Thanks in advance for your help!

OSGi: What happens when an imported service is stopped while the service is still running

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.

Always resolve type in new Lifetimescope?

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.