I'm creating a framework with showcase composables of core functionalities (in this case some ecommerce product lists, categories etc.). The main point is that we will just need to swap the url of the client and maybe add an interceptor (in this case I apollo graphql but in retrofit it would be the same) and we will be able to use these composables with loaded data. Here's the problem: Since I'll probably want to use hilt how do I pass the url and/or interceptors to the framework? I thought about some sort of init function but the hilt classes are generated during build, so I'd somehow have to pass it during runtime. Is that even possible? Or maybe there are some good alternatives to that approach?
Related
I am building a library that every 30 seconds displays a question (obtained from a REST Api) and allows the user to select one of the possible answers.
Also, I need to make use of that library in an app, displaying a video underneath the question.
Desired result
All the business and UI logic should be handled in the library.
Does it make sense to use an MVVM approach, with repository pattern in the library?
With this package structure?
Possible package structure
You're creating the library, which is totally different context and way of creating the codebase comparing to the app.
First of all you need to make decisions about the dependencies. Of course it is super easy to put retrofit, mvvm and other dependencies into the app and manage them further.
With library it's not that easy. What I would expect from library in the first place is to have as little dependencies as possible. If you're going to provide aar file, then the developer would have to include those dependencies in the project. On the other hand, if you're publishing the library to maven repo, the gradle will take care of the library's dependencies. However the biggest challenge here is maintaining the library and resolving conflicts in actual app that uses the library. It can lead to frustration and eventually someone can throw your library away, which is the worst thing from library creator's perspective.
What I would suggest for this small library (calling api and providing data to custom view) is to:
Use only OkHttp without retrofit to provide the data from the REST api.
If it's the case for the library, create some abstraction over the OkHttp client with public functions/methods so the developers can get the data by themselves. Cool approach for creating this kind of interface is to use Fluent Interface (for example if you want the client of the library to put their access token/secret key for the REST api to detect who is calling the api, how much, limit their requests etc)
If you want to also provide the Custom View I would suggest to think twice about separating the REST client and Custom View itself and let the developer put the data by themselves. On the other hand if you want to handle it by yourself, you have to consider error handling, state management, lifecycle callbacks for cancelling the requests etc. You can provide some Listener interfaces for the developers so they know what is going on in the custom view.
The way you structure the library is up to you, if you have only one dependency (the rest client) just pass the objects via constructor so you won't need to add another dependency. Or just simply use ServiceLocator pattern, however it should also be connected to the Application/Activity itself when setting up the library so the objects are destroyed properly
If you look at the diagram Google has published on how to architect an Android app:
https://developer.android.com/jetpack/docs/guide
you'll notice that it appears that a single repository is used abstract access to cached data and data accessed over the web. I presume that this repository is a single class and have indeed seen apps built that do have one large repository.
But this raises the question about how Dagger is used when dealing with something like a repository. In my app, I will have classes that will at times need to access cached data from local storage or using Room. Then there are REST api calls that retrieve data.
What bothers me is that if I create a single repository, I really don't want classes instantiated for the cache when the cache is not being used or instantiating classes to handle REST apis when caching is required. In other words, it seems senseless to create a component using Dagger that includes modules for local data access and web access. I want to avoid Dagger from instantiating all these classes at once and having them reside in memory while the app runs. A better solution is to only instantiate the stuff I need when I need it.
How should this be handled in Dagger? Should two separate components be used in the repository or is there some other mechanism that only creates instances of the classes I need when they are required?
It is based on the Java Specification Request (JSR) 330. It uses code generation and is based on annotations. The generated code is very relatively easy to read and debug.
1) Dagger provide simplifies access to shared instances
- That means If we declare #Inject annotation in our code then we can get reference everywhere in our projects
2) Easy configuration of complex dependencies
dagger follow the implicit order and generate Objects so in dependency and generated code both are easy to understand and traced and we can reduce large boilerplate of code,
normally we can hand to obtain reference and pass them to other objects so we can focus on modules the build rather then focusing the order in which they need to be created
3) Easier unit and integration testing Because dependency graph is created for us so its easily swap out module,network response
I'm trying to figure out dagger and having a hard time to grasp the concept of the object graphs.
I'm not new to the dependency injection paradigm, I used angular.js in JavaScript and prism in .Net. So I do understand the idea behind it.
What I can't seem to understand is whether the object graph should be actually a single graph, meaning one in all the app and all the dependencies should be injected from it or should I create one for each module.
I want to create an instance of a class with injectables, so should I use an existing object graph or create a new one?
Where is best practice to create multiple mudules ? Should I create object graph per module as a singleton? Create one object graph for all the app that every class should use? Or should I create a new object graph each time I need a new instance?
Thanks
Think of Object Graphs or Components (if using dagger2) as a way to scope objects. You mentioned you used .Net so I am assuming you are familiar with scoping. Rather than creating a graph for each module I would recommend creating an object graph for each scope. A common pattern is to have an Application scope and then "plus" the activity graph/component onto the Application scope. You can have 1 to many modules per component. Modules are more of a way to split dependencies into different files (even thought they may still be in same component). CodePath has a pretty good intro on Dagger including going into scopes as well as multiple modules per component. Best of Luck! https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2
Android lets us extend Application, which is a great place to store our singletons so they can be easily reused throughout different pages (actiivities) in the app.
What is Google App-Engine's equivalent of this?
I am using dagger, and I don't want to create a new object graph for every endpoint.
One option (although I'm by no means sure it's the best) is just to self-inject your Cloud Endpoints class (through static field injection).
Presumably you're initialising the object graph in a ServletContextListener so you could do so there, before your endpoint methods are called.
Dagger 1.x supports staticInjections on the module annotation (to do that for you) but this is apparently no longer supported in 2.x.