Autofac- externally owned container? - autofac

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.

Related

What are the memory management differences between Get.put(SomeClass(), permanent: true) and Get.put(SomeGetXService())

I am using Getx and its dependency injection mechanism.
sometime I am overthinking - should I inject a class that should remain in memory (for good as a Singelton) using
Get.put(SomeClass(), permanent: true)
or using
Get.put(SomeGetXService())
by reading the documentation, both ways seems to put the class in memory as Singelton, and it can only be deleted explicitly (i.e. not with Get.smartManagement).
as for me, I prefer not to extend the class with GetxService, since the first option is simpler to implement - but I feel like I might be missing something. having the class in memory as Singelton through out the app life-span is a must.
Thanks for your help
The first option always keeps the class in memory throughout the entire app's lifespan, while the second option binds the service to the stack navigation lifecycle. According to GetX dpcumentation, a GetXService is only deleted with a call to Get.reset(). In most cases though, both methods will probably be equally valid, since in essence, a service is kept in memory throughout the entire app lifecycle anyways.

Why do we need event.stopPropagation() in DOM? Is it bad architectural pattern?

In the everyday front-end development I often use DOM as a global event bus that is accessible to every part of my client-side application.
But there is one "feature" in it, that can be considered harmful, in my opinion: any listener can prevent propagation of an event emitted via this "bus".
So, I'm wondering, when this feature can be helpful. Is it wise to allow one listener to "disable" all the other? What if that listener does not have all information needed to make right decision about such action?
Upd
This is not a question about "what is bubbling and capturing", or "how Event.stopPropagation actually works".
This is question about "Is this good solution, to allow any subscriber to affect an event flow"?
We need (I am talking about current usage in JS) stopPropagation() when we want to prevent listeners to interfere with each other. However, it is not mandatory to do so.
Actual reasons to avoid stopPropagation:
Using it usually means that you are aware of code waiting for the same event, and interfering with what the current listener does. If it is the case, then there may (see below) be a design problem here. We try to avoid managing a single thing at multiple different places.
There may be other listeners waiting for the same type of event, while not interfering with what the current listener does. In this case, stopPropagation() may become a problem.
But let's say that you put a magic listener on a container-element, fired on every click to perform some magic. The magic listener only knows about magic, not about the document (at least not before its magic). It does one thing. In this case, it is a good design choice to leave it knowing only magic.
If one day you need to prevent clicks in a particular zone from firing this magic, as it is bad to expose document-specific distinctions to the magic listener, then it is wise to prevent propagation elsewhere.
An even better solution though might be (I think) to have a single listener which decides if it needs to call the magic function or not, instead of the magic function being a stoppable listener. This way you keep a clean logic while exposing nothing.
To provide (I am talking about API design) a way for subscribers to affect the flow is not wrong; it depends on the needs behing this feature. It might be useful to the developers using it. For example, stopPropagation has been (and is) quite useful for lots of people.
Some systems implement a continueX method instead of stopX. In JavaScript, it is very useful when the callees may perform some asynchronous processing like an AJA* request. However, it is not appliable to the DOM, as the DOM needs results in time. I see stopPropagation as a clever design choice for the DOM API.

DOM manipulation in AngularJS services

It's well known that you must manipulate DOM elements inside directives when using AngularJS.
However, it seems that, in some use cases, manipulating DOM inside a service is acceptable.
Misko Hevery is talking about this here. You can also find an example within the Bootstrap UI Dialog.
Misko's explanation is rather vague so I was wondering how do you determine when you need to put DOM inside a service instead of a directive.
A directive, with the way it is defined, is always attached to a DOM node. So when you define a directive, it "expands" or replaces the DOM node to which it is attached.
In certain situations (like dialogs) you won't be able to attach DOM nodes to any specific parent. In these cases using a service makes sense and the controller can still stay out of the DOM bit because the DOM manipulation will be encapsulated in a service..
Popups could be another situation where we could probably use a service, but unlike a dialog, a popup IS attached to a DOM node. So, even that is slightly a grey area.
So, a basic and simple test is, "Can this bit of DOM Manipulation code be attached to a DOM node?" If yes, then directive. If no, then service.
Dialogs and Custom Confirm Boxes come in as typical examples where you would use a service.
Whilst I think Ganaraj has described what Misko was saying well, you could (and potentially should) argue that the DOM manipulation code for a modal dialogue (for example) can be put into a DOM node.
One approach is to have a dialog directive attached to the DOM the whole time, and then use ng-show to conditionally show it. You can then communicate with the modal dialog using either $rootScope, or better: a service.
I actually prefer this approach because it feels 'right' - the service handles the transfer of data and the directives interact with the service to make sure it gets displayed in a way that makes sense to the user.
But I think the fact that Misko is not particularly clear about it shows that it's quite subjective. Do what makes the most sense to you.
I'm googling this topic to reinforce my inner feeling about this because I'm working on an issue right now that makes me want to place certain logic in a service. Here's my case, and what I think is a plenty good justification for putting dom-based handling in service:
I have directive-based elements that react to mouse position, globally (e.g. they move or change in some way based off mouse position). There are an indeterminate number of these elements and they don't pertain to any specific location in the application (since it's a GUI element and can pertain to any container anywhere). If I were to adhere to the strict angular "dom logic in the directives only" rule, it'd be less efficient because the elements all share the logic pertaining to parsing the mouse position (efficiently) which revolves around window.requestAnimationFrame ticks.
Were I to bundle that logic into the directive, I'd have a listener/raf loop tied to every single instance. While it'd still be DRY, it wouldn't be efficient since on every move of the mouse you'd be firing the exact same listener that would return the exact same result for every single element.
It's actually best in this case to move this into a service, despite it being dom-based logic, and register each directive instance against the service to call the same, instance-based logic against the logic performed that would be duplicate for each instance.
Remember, while Angular provides some very good advice around how to structure you code, that does not make it bullet proof of by any means a hard and fast rule, since it can't possibly cover all use cases. If you see a hole where the "best practices" seem to fail, its because you're actually properly understanding the best practices, and you've now found a reason to break the rules on purpose.
That's just my 2 cents!!
I agree with #dudewad. At the end of the day a service (factory, provider, value) is just angular's module pattern with the limitation of being implemented as a singleton. I think it's important that you get access to the DOM via an element that is passed into a directive's link function and not by using document or other global approaches. However, I don't think that it's important that the logic that you apply to dom element that you get from a directive lives in the same module. For SRP reasons it can be favorable to break up the code a bit using a service as you might have a particularly complex piece of logic that it makes more sense to have focused test around or you might want to use the logic in more than one directive as pointed out by #dudewad.
one drawback to using a DOM manipulation method based off of changing a variable (ie, ng-show="isVisible") is that the DOM manipulation occurs after the next "javascript turn" loop (when isVisible is updated). You may need the DOM to be updated right away.
For example, a common scenario is displaying a "spinner" during transitions to a new route / state. If you were to set $scope.isVisible = true on the $routeChangeStart / $stateChangeStart event, and then $scope.isVisible = false on the $routeChangeSuccess / $stateChangeSuccess event, you will never see your ng-show, as the whole route / state change happens within one javascript turn. It would be better to use .show() and .hide() in those events so that you actually see the spinner.
to bring this all back and make it relevant to the OP's question -- in a situation where the DOM manipulation is a "spinner" modal being displayed, I would do it during the service, and I would do it with direct DOM manipulation methods, rather than relying on a model change.

Why use the Bundle when you can just use the Application?

I'm reading this article on how to : correctly retain variable state in Android and I'm reminded that I've never gotten a good answer (and can't find one here) for why it's better to tussle with the Bundle (which isn't a HUGE hassle, but definitely has its limitations) rather than just always have an Application overridden in your App, and just store all your persistent data members there. Is there some leakage risk? Is there a way that the memory can be released unexpectedly? I'm just not clear on this... it SEEMS like it's a totally reliable "attic" to all the Activities, and is the perfect place to store anything that you're worried might be reset when the user turns the device or suspends the app.
Am I wrong on this? Would love to get some clarity on what the true life cycle of the memory is in the Application.
Based on the answers below, let me extend my question.
Suppose I have an app that behaves differently based on an XML file that it loads at startup.
Specifically, the app is a user-info gathering app, and depending on the XML settings it will follow an open ended variety of paths (collecting info A, but not J, and offering Survey P, followed by an optional PhotoTaking opportunity etc.)
Ideally I don't have to store the details of this behavior path in a Bundle (god forbid) or a database (also ugly, but less so). I would load the XML, process it, and have the Application hold onto that structure, so I can refer to it for what to do next and how. If the app is paused and the Application is released, it's not *THAT big a hassle to check for null in my CustomFlow object (that is generated as per the XML) and re-instantiate it. It doesn't sound like this would happen all that often, anyway. Would this be a good example of where Application is the *best tool?
The question as to which method is better largely depends upon what information you are storing and need access to and who (which components, packages, etc.) needs access to that information. Additionally, settings like launchMode and configChanges which alter the lifecycle can help you to determine which method is best for you.
First, let me note, that I am a huge advocate for extending the Application object and often extend the Application class, but take everything stated here in its context as it is important to understand that there are circumstances where it simply is not beneficial.
On the Lifecycle of an Application: Chubbard mostly correctly stated that the Application has the same life as a Singleton component. While they are very close, there are some minute differences. The Application itself is TREATED as a Singleton by the OS and is alive for as long as ANY component is alive, including an AppWidget (which may exist in another app) or ContentResolver.
All of your components ultimately access the same object even if they are in multiple Tasks or Processes. However, this is not guaranteed to remain this way forever (as the Application is not ACTUALLY a Singleton), and is only guaranteed in the Google Android, rather than the manufacturer overridden releases. This means that certain things should be handled with care within the Application Object.
Your Application object will not die unless all of your components are killed as well. However, Android has the option to kill any number of components. What this means is that you are never guaranteed to have an Application object, but if any of your components are alive, there IS an Application to associate it to.
Another nice thing about Application is that it is not extricably bound to the components that are running. Your components are bound to it, though, making it extremely useful.
Things to Avoid in Application Object:
As per ususal, avoid static Contexts. In fact, often, you shouldn't store a Context in here at all, because the Application is a Context itself.
Most methods in here should be static, because you are not guaranteed to get the same Application object, even though its extremely likely.
If you override Application, the type of you data and methods store here will help you further determine whether you need to make a Singleton component or not.
Drawables and its derivatives are the most likely to "leak" if not taken care of, so it is also recommended that you avoid references to Drawables here as well.
Runtime State of any single component. This is because, again, you are not guaranteed to get back the same Application object. Additionally, none of the lifecycle events that occur in an Activity are available here.
Things to store in the Application (over Bundle)
The Application is an awesome place to store data and methods that must be shared between components, especially if you have multiple entry points (multiple components that can be started and run aside from a launch activity). In all of my Applications, for instance, I place my DEBUG tags and Log code.
If you have a ContentProvider or BroadcastReceiver, this makes Application even more ideal because these have small lifecycles that are not "renewable" like the Activity or AppWidgetProvider and can now access those data or methods.
Preferences are used to determine, typically, run options over multiple runs, so this can be a great place to handle your SharedPreferences, for instance, with one access rather than one per component. In fact, anything that "persists" across multiple runs is great to access here.
Finally, one major overlooked advantage is that you can store and organize your Constants here without having to load another class or object, because your Application is always running if one of your components is. This is especially useful for Intent Actions and Exception Messages and other similar types of constants.
Things to store in Bundle rather than Application
Run-time state that is dependent upon the presence or state of a single component or single component run. Additionally, anything that is dependant upon the display state, orientation, or similar Android Services is not preferrable here. This is because Application is never notified of these changes. Finally, anything that depends upon notification from that Android System should not be placed here, such as reaction to Lifecycle events.
And.... Elsewhere
In regard to other data that needs to be persisted, you always have databases, network servers, and the File System. Use them as you always would have.
As useful and overlooked as the Application is, a good understanding is important as it is not ideal. Hopefully, these clarifications will give you a little understanding as to why gurus encourage one way over the other. Understand that many developers have similar needs and most instruction is based on what techniques and knowledge a majority of the community has. Nothing that Google says applies to all programmer's needs and there is a reason that the Application was not declared Final.
Remember, there is a reason Android needs to be able to kill your components. And the primary reason is memory, not processing. By utilizing the Application as described above and developing the appropriate methods to persist the appropriate information, you can build stronger apps that are considerate to the System, the User, its sibling components AND other developers. Utilizing the information that everyone here has provided should give you some great guidance as to how and when to extend your Application.
Hope this helps,
FuzzicalLogic
I prefer to subclass Application and point my manifest to that. I think that's the sane way of coding android although the Android architects from Google think you should use Singletons (eek) to do that. Singletons have the same lifetime as Application so everything that applies to them applies to Application except much less dependency mess Singletons create. Essentially they don't even use bundles. I think using subclass Application has dramatically made programming in Android much faster with far less hassle.
Now for the downside. Your application can be shutdown should the phone need more memory or your Application goes into the background. That could mean the user answered the phone or checked their email. So for example, say you have an Activity that forces the user to login to get a token that other Activities will use to make server calls. That's something you might store in your service object (not android service just a class that sends network calls to your server) that you store in your subclass of Application. Well if your Application gets shutdown you'll loose that token, and when the user clicks the back button your user might return to an Activity that assumes you are already authenticated and boom your service class fails to work.
So what can you do? Continue to use Bundle awfulness? Well no you could easily store security tokens into the bundle (although there might be some security issues with that depending on how this works for your app), or you have to code your Activities to not assume a specific state the Application is in. I had to check for a loss of the token and redirect the user back to the login screen when that happens. But, depending on how much state your Application object holds this could be tricky. But keep in mind your Application can know when it's being shutdown and persist it's internal state to a bundle. That at least allows you to keep your Objects in memory for 99% of the time your Application, and only save/restore when it gets shutdown rather than constantly serializing and deserializing with boiler plate code whenever you move between Activities. Using Application lets you centralize how your program can be brought up and shutdown, and since it normally lives longer than any one activity it can reduce the need for the program to reconstitute the guts of your App as the user moves between Activities. That makes your code cleaner by keeping out details of the app from every Activity, reduces overhead if your Application is already built, shares common instances/code, and allows Activities to be reclaimed without loosing your program all together. All good programs need a centralized hub that is the core, and subclassing Application gives you that while allowing you to participate in the Android lifecycle.
My personal favorite is to use http://flexjson.sourceforge.net/ to serialize my Java objects into bundles as JSON if I need to send objects around or save them. Far easier than writing to sqlite DB when all you need to do is persist data. And nice when sending data between two Activities using objects instead of broken apart primitives.
Remember by centralizing your model in the Application you create a place to share code between multiple Activities so you can always delegate an Activities persistence to an object in the Application by hooking the onPause() as well allowing persistence to be centrally located.
The short answer is: use bundles as it makes saving your state out when you're backgrounded easier. Also, it's complicated.
The long answer:
My understanding is, as soon as you Activity's onPause method is called (and onSaveInstanceState which gives you a bundle into which you should store your Activity's data) your process can be terminated without further warning. Later, when the user comes back to your application, your activity is given an onCreate call with that original bundle from which to restore its state. This will happen to all your activitys in what was your original stack.
Being able to restore your state from the bundle (which Android will save for you as your process goes away) is how Android maintain's the myth of multi-tasking. If you don't dump your activity's state out to a bundle each time onSaveInstanceState is called, your app will look like it's been restarted when the user may have just switched out for a second. This can be especially troubling when the system is resource constrained as the system would need to kill off processes more often in order to keep the device running quickly
Why the Application can be Bad
The Application does not actually get a chance to save any of its data if the process is shut down. It does have an onDestroy method but the docs will tell you that this actually never gets called by the system on an actual device. This means that, in the constrained case I mentioned above, any incidental information about what's going on within an Activity (if you've saved it in the Application) will be lost if the process is ended.
Developer's often miss this case (and it can be really annoying for users) because they're either running on a dev phone which never gets hit with using many applications at the same time. We're also never using the app for a while, then switching to another application and, after a while, switching back again.

Can components be temporarily registered in an Autofac container?

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.