Dagger2命名(@Named)注入多态或不同的对象

时间:2016-10-22 17:05:12

标签: java dependency-injection dagger-2

您好我正在尝试在Dagger2中研究命名注射

这是我的Java类,但它们似乎都没有工作。 我想要的是基于@Named注释我希望获得不同的对象。

public interface Server {

    public void start();

    public void stop();

    public String request(String request);
}

public abstract class AbstractServer implements Server {

    private boolean started;

    @Override
    public void start() {
        started = true;
    }

    @Override
    public void stop() {
        if (!started) {
            throw new IllegalStateException("Server was not started");
        }
    }
}

public class AudioServer extends AbstractServer{

     @Override
    public String request(String request) {
        return "Response from Audio server: " + request;
    }

}

public class VideoServer extends AbstractServer {

    @Override
    public String request(String request) {
        return "Response from Video server: " + request;
    }
}

@Module
public class ServerModule {

    public ServerModule() {
    }

    @Provides
    @Named("audio")
    @Singleton
    AudioServer provideAudioServer() {
        return new AudioServer();
    }

    @Provides
    @Named("video")
    @Singleton
    VideoServer provideVideoServer() {
        return new VideoServer();
    }
}

请不要ServerComponent.java没有编译

@Singleton
@Component(modules = {ServerModule.class})
public interface ServerComponent {

    AudioServer provideAudioServer();

    VideoServer provideVideoServer();

    void inject(TestInject inject);

}

public class TestInject {

    private static final Logger logger = Logger.getLogger(TestInject.class.getSimpleName());

    @Inject
    @Named("audio")
    Server audioServer;

    public TestInject() {
//        ServerComponent component = DaggerServerComponent.builder()
//                .build();
//        component.inject(this);
    }

    public void test() {
        String serverResponse = null;
        if (audioServer != null) {
            serverResponse = audioServer.request("game.mp3");
            logger.warning(serverResponse);
        } else {
            serverResponse = "Failure";
            logger.info(serverResponse);
        }
    }

    public static void main(String[] args) {
        TestInject inject = new TestInject();
        inject.test();
    }
}

已审核请在TestInject.javaServerComponent.java

中查看答案
public interface Server {

    public void start();

    public void stop();

    public String request(String request);
}

public abstract class AbstractServer implements Server {

    private boolean started;

    @Override
    public void start() {
        started = true;
    }

    @Override
    public void stop() {
        if (!started) {
            throw new IllegalStateException("Server was not started");
        }
    }
}

public class AudioServer extends AbstractServer{

     @Override
    public String request(String request) {
        return "Response from Audio server: " + request;
    }

}

public class VideoServer extends AbstractServer {

    @Override
    public String request(String request) {
        return "Response from Video server: " + request;
    }
}

@Module
public class ServerModule {

    public ServerModule() {
    }

    @Provides
    @Named("audio")
    @Singleton
    AudioServer provideAudioServer() {
        return new AudioServer();
    }

    @Provides
    @Named("video")
    @Singleton
    VideoServer provideVideoServer() {
        return new VideoServer();
    }
}

请不要ServerComponent.java没有编译

@Singleton
@Component(modules = {ServerModule.class})
public interface ServerComponent {

    @Named("audio")
    Server provideAudioServer();

    @Named("video")
    Server provideVideoServer();

    void inject(TestInject inject);
}

    public class TestInject {

    private static final Logger logger = Logger.getLogger(TestInject.class.getSimpleName());

    @Inject
    @Named("audio")
    Server audioServer;

    @Inject
    @Named("video")
    Server videoServer;

    public TestInject() {
        ServerComponent component = DaggerServerComponent.builder()
                .build();
        component.inject(this);
    }

    public void testAudioServer() {
        String serverResponse = null;
        if (audioServer != null) {
            serverResponse = audioServer.request("game.mp3");
            logger.warning(serverResponse);
        } else {
            serverResponse = "audio server Failure";
            logger.info(serverResponse);
        }
    }

    public void testVideoServer() {
        String serverResponse = null;
        if (videoServer != null) {
            serverResponse = videoServer.request("movie.mp4");
            logger.warning(serverResponse);
        } else {
            serverResponse = "Video server Failure";
            logger.info(serverResponse);
        }
    }

    public static void main(String[] args) {
        TestInject inject = new TestInject();
        inject.testAudioServer();
        inject.testVideoServer();
    }
}

1 个答案:

答案 0 :(得分:1)

您的主要问题似乎与您希望在课程TestInjectServer名为audio而您的提供者返回AudioServer这一事实有关,因此匕首无法满足您的要求依赖。

确实不要忘记注释@Named用于区分同一类型的2个对象,换句话说,您可以使用@Named("audio")不同的提供商进行注释只要他们没有返回相同的类型。然后,生成的对象将通过其类型和名称进行标识。

例如,这里有一种解决问题的方法:

班级TestInject

public class TestInject {
    ...

    public TestInject() {
        // Needed to inject your dependencies
        ServerComponent component = DaggerServerComponent.builder()
            .build();
        component.inject(this);
    }
    ...
}

班级ServerComponent

@Singleton
@Component(modules = ServerModule.class)
public interface ServerComponent {
    void inject(TestInject inject);
}

班级ServerModule

@Module
public class ServerModule {

    @Provides
    @Named("audio")
    @Singleton
    public Server provideAudioServer() {
        return new AudioServer();
    }

    @Provides
    @Named("video")
    @Singleton
    public Server provideVideoServer() {
        return new VideoServer();
    }
}

即使您的问题更新,您的模块应该是我建议的,否则它不会因为前面描述的相同原因而编译。