问题
I'm using Dagger for Android for dependency injections. I have a UserService object in a Main Class:
public class Main implements Runnable {
@Inject
UserService service;
@Override
public void run() {
for (User f : service.getUserByName("toto")) {
System.out.print(f.getM_Nom());
}
}
public static void main(String[] args) {
ObjectGraph objectGraph = ObjectGraph.create(new UserModule());
Main m = objectGraph.get(Main.class);
m.run();
}
}
I managed to inject the "service" field and to call the method "getUserByName("")". But in my "UserService", I have an other custom object ("RepositoryUser" class):
public class UserService implements IUserService {
@Inject
RepositoryUser m_Repository;
@Override
public List<User> getUserByName(String name) {
return m_Repository.getAll();
}
}
My problem is that this field is not inject: the "m_Repository" field is null and I get a null pointer exception when I try to use my RepositoryUser object.
Here is my Provider:
@Module(
injects = {UserService.class, Main.class, RepositoryUser.class}
)
public class UserModule {
@Provides
RepositoryUser provideRepositoryUser() {
return new RepositoryUser();
}
@Provides
UserService provideUserService() {
return new UserService();
}
}
Any idea ?
Thanks in advance !
回答1:
It is preferrable to use Constructor Injection in this case. This can be achieved as follows:
Main:
public class Main implements Runnable {
private final IUserService service;
@Inject
public Main(IUserService service) {
this.service = service;
}
@Override
public void run() {
for (User f : service.getUserByName("toto")) {
System.out.print(f.getM_Nom());
}
}
public static void main(String[] args) {
ObjectGraph objectGraph = ObjectGraph.create(new UserModule());
Main m = objectGraph.get(Main.class);
m.run();
}
}
UserService:
public class UserService implements IUserService {
private final RepositoryUser m_Repository;
@Inject
public UserService(RepositoryUser repository) {
m_Repository = repository;
}
@Override
public List<User> getUserByName(String name) {
return m_Repository.getAll();
}
}
RepositoryUser:
public class RepositoryUser {
@Inject
public RepositoryUser() {
}
/* ... */
}
UserModule:
@Module(injects = Main.class)
public class UserModule {
@Provides
IUserService provideIUserService(UserService userService){
return userService;
}
}
Everywhere the @Inject
annotation is present on a constructor, Dagger can automatically create an instance of that item. So when you request a RepositoryUser
instance in the UserService
constructor, Dagger will see the @Inject
annotation on RepositoryUser
's constructor, and use that to create a new instance. We do not need an @Provides
method here.
The IUserService
parameter on the Main
constructor cannot be instantiated, since it is an interface. Using the provideIUserService
method in the module, we tell Dagger that we want it to create a new UserService
instance.
We do have an @Inject
annotation on the Main
constructor, but we request it using ObjectGraph.get(Class<T> clzz)
. Therefore, we need to add injects = Main.class
to our module.
来源:https://stackoverflow.com/questions/27606149/android-ioc-dagger-framework-how-to-inject-a-nested-field