How do I check if all Dagger dependencies for a component are scoped? - dagger-2

I’m converting a large service to use Dagger, and I have a component with a lot of dependencies in the generated graph, and I want to ensure everything is scoped.
Initially, I tried to look at all the modules of the component to ensure that all their #Provides were annotated with a scope. However, one can have a class that uses #Inject, not have any #Provides methods in the modules, and that be unscoped if not specified on the class.
Right now, in order to check if I missed anything, I go into the generated code and look to see if anything is missing a double-checked locked provider. However, this isn’t very efficient and feels error-prone, as there are cases (such as a component dependency) where we don’t need a provider, since we reference the dependent component directly.
Is there a simple way to check for unscoped bindings for a component? I’d like to make sure that for the component, only one instance of every object in its graph is created in its lifetime.

Related

Dagger2 - should an activity component be a sub-component of other?

I used #subcomponent mostly for case activities need to use some shared objects from application component, or fragments components want to use some objects provided by container activity.
Now I am wondering if I can make some activity components be subcomponent of another activity component. For example, the TaskDetailActivity has a task object and want to provide to some other activities such as TaskParticipantActivity, TaskProgressActivity and some fragments.
The traditional way to provide task object to other activities is set it into intent object, but how about if we want to use Dagger2 for this case?
Update: my sistuation similar with the case of UserScope in this article http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/, but instead of saving the user component in Application class, can I save in an activity, i.e TaskDetailActivity?
Components are for grouping objects of a similar lifecycle. While Components may happen to correspond to a particular set of functionality (like a TaskComponent for injecting a TaskActivity and a TaskPresenter) it is not always possible or desirable to insist on only one Component per set of functionality (for instance, insisting on only one TaskComponent for all task related activities and dependencies).
Instead, in Dagger 2 re-usability is available through Modules which you can very easily swap in and out of Components. Within the constraints of the advice for organising your Modules for testability in the Dagger 2 official documentation you are able to organise Modules congruent with your functionality (e.g., a TaskModule for all-task related dependencies). Then, because Components are so lightweight, you can make as many as you like to deal with the different lifecycles of your Activities and so on. Remember also that you can compose Modules using the Class<?> [] includes() method inside the Module #interface.
In your particular scenario, you want to share the Task object from a TaskDetailActivity. If you held a reference to the Task within your TaskDetailActivity then that reference will no longer be available when TaskDetailActivity is destroyed. While you could try some solution of holding binding the Task in a Module and then maintaining a reference to that Module at the app-scope level, you would essentially be doing the same as the UserScope at the app-scoped level in the article you have linked. Any kind of solution for sharing the Task object between Activity using Dagger 2 would necessarily involve maintaining a reference to the object at the app-scoped level.
Using Dagger 2 doesn't mean that the new keyword or serialization/deserialization of Parcelables is now wrong and so if your first intuition is to use Intent to communicate then I would say that you are right. If you need a more robust solution than directly communicating the Task, then you could extract a TaskRepository and transmit an Intent between Activity that contains the id of the Task you wish to retrieve. Indeed, some of the Google Android Architecture Blueprints have a solution just like this.

How to use modules in dagger-2

I can't seem to grasp the modules of dagger.
Should I create a new instance of a module each time I want to inject stuff?
Should I create only one instance of a module? If so where should I do it?
Is there a more complex example of fragments and activities used with dagger?
Thanks
You should think more about #Component than #Module. Modules just create objects that need further initialization. The actual work happens in Components, which modules are part of.
Should I create a new instance of a module each time I want to inject stuff?
You should create your module when you create the Component it is part of, since only this component is going to need it. If you find yourself creating the same module multiple times, you are most likely doing something wrong.
A module uses additional arguments (pass them in via the constructor) to create more complex objects. So if you were to have e.g. a UserModule you'd pass in the a user to create user dependent objects from the resulting component. If the user changes lose the old component and create a new module and a new component—the old objects should not be used anymore.
Keep the component where / when appropriate and be sure to use Scopes, since they determine the lifetime of your component.
Should I create only one instance of a module? If so where should I do it?
You most likely will just create a single instance of #Singleton annotated Components and Modules. In android you'd most likely keep the reference to the component (not the module!) in the Application or some real 'singleton'.
Is there a more complex example of fragments and activities used with dagger?
Try googling. There are lots of high quality tutorials with linked github repositories that go into much more depth and detail as would be possible here on SO. e.g. see Tasting dagger 2 on android.

Implementing Chain of Responsibility with Services

I'm thinking about a platform-neutral (i.e. not .NET MEF) technique of implementing chain-of-responsibliity pattern using web services as the handlers. I want to be able to add more CoR handlers by deploying new services and not compiling new CoR code, just change configuration info. It seems the challenge will be managing the metadata about available handlers and ensuring the handlers are conforming to the interface.
My question: any ideas on how I can safely ensure:
1. The web services are implementing the interface
2. The web services are implementing the base class behavior, like calling the successor
Because, in compiled code, I can have type-safety and therefore know that any handlers have derived from the abstract base class that ensures the interface and behavior I want. That seems to be missing in the world of services.
This seems like a valid question, but a rather simple one.
You are still afforded the protection of the typing system, even if you are loading code later, at runtime, that the original code never saw before.
I would think the preferred approach here would be to have something like a properties file with a list of implementers (your chain). Then in the code, you are going to have to have a way to instantiate an instance of each handler at runtime to construct the chain. When you construct the instance, you will have to check its type. In Java, for instance, that would take the form of instanceof (abomination ordinarily, but you get a pass for loading scenarios), or isAssignableFrom. In Objective C, it's conformsToProtocol.
If it doesn't, it can't be used and you can spit an error out to the console.

How to achieve a reference-counted shared instance in Autofac?

I have a service IService that several components depend on. The components come and go depending on user actions.
It so happens that the implementation of IService is expensive, and I want 1 instance shared across all components. So far so good, I can use:
builder.RegisterType<ExpensiveStuff>().As<IService>().SingleInstance();
However, I don't want to ExpensiveStuff to live forever once built; I only want it to exist when one or more components holds a reference to it.
Is there a built in means of achieving this in Autofac?
I think you'll have to make sure that your usage of those dependencies happen within an instance scope.
The Orchard project could be a source of inspiration here. They use a set of scopes for Unit of Work; see the ShellContainerFactory.cs source file.

Zend Framework: Resource Plugins vs Methods

i was reading Zend Framework Book: Survive the Deep End about resource methods. it speaks about how resource methods will override resource plugin.
But wait, there's also a Resource
Plugin
(Zend_Application_Resource_View) which
may also create a Resource called
View. Can we have two View Resources?
The answer is no - we can have one and
one only
in Zend Framework Manual,
a good way to create re-usable
bootstrap resources and to offload
much of your coding to discrete
classes is to utilize resource plugins
... the intention is that developers
should write their own to encapsulate
their own initialization needs
to me, resource methods seem like a more intuitive way to initialize resources, why then should I use plugins? is it just a question of which do I prefer? or are they used in different circumstances?
will resource methods replace or add to the functionality provided by the provided resource plugins? because if it replaces, I would need to make sure i initialize all variables or whatever I need?
By returning the new Zend_View
instance from _initView(),
Zend_Application will accept the
replacement and will not attempt to
overwrite our changes by running
Zend_Application_Resource_View to set
up a standard default Zend_View
instance with the flaws we just
corrected
if I dont return a Zend_View, it will be as if I didn't have the method? can I say that I should always return something from resource methods?
Here, we do the same thing by using
the getResource() method to retrieve
an instance of Zend_Controller_Front
created and configured by
Zend_Application_Resource_Frontcontroller
from the above, can i say that if i want my resource methods to have the defaults set by the provided resource plugin, i can do a getResource() 1st?
Answering your questions:
Should I use resource plugins or methods?
I would say it's largely down to personal preference. As your quote from the manual says, if you use a resource plugin, it becomes easier to reuse the code in another project (as it's easier to move around/test a class than it is to cut'n'paste text from a method). In my opinion methods make it a little easier to see what's going on in the bootstrap, at least until they start becoming a bit complex, in which case it'd make sense to convert them into a plugin.
Will resource methods replace or add to the functionality provided by resource plugins?
I believe the way it works is that plugins are loaded up and initialised when the bootstrap class is first instantiated. The bootstrap will then go through your methods and run those. If you have a method named the same as a plugin resource, your method will override that plugin. However you can also access the existing resource from your method and modify it, in which case your method is adding to the functionality provided by the plugin.
Remember that plugins don't magically run by themselves (apart from the front controller plugin, which will always run). They will only be used if your application.ini triggers them (or if you call them from your own methods).
If I dont return a Zend_View, it will be as if I didn't have the method? can I say that I should always return something from resource methods?
It is good practice to return something from resource methods as this allows that resource to be accessed by other methods or other parts of the application. However the method will still run without the return value. But if you added an _initView method and setup a new Zend_View object, if you don't do anything with it it won't have any effect on your application.
Can i say that if i want my resource methods to have the defaults set by the provided resource plugin, i can do a getResource()
Yes. But I would make sure you return the resource in this case, just so that any other methods that access the resource are using your modified one rather than the one setup by the plugin.
Personally I would either stick to application.ini + resource plugins, or resource methods. It's easier to see what's going on if all of the resource stuff is in one place.