java - Dagger2 Named(@Named) 多态或不同对象注入(inject)

标签 java dependency-injection dagger-2

你好,我正在尝试研究 Dagger2 中的命名注入(inject)

这是我的 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();
    }
}

最佳答案

您的主要问题似乎与您期望在类 TestInject 中有一个名为 audioServer 而您的提供者返回 AudioServer 所以 dagger 不能满足你的依赖。

确实不要忘记注解@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();
    }
}

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

关于java - Dagger2 Named(@Named) 多态或不同对象注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40194779/

相关文章:

c# - .NET Core 2.1 - 在 NPE 中设置 Azure Insights 采样配置结果

angularjs - 是否可以自动注入(inject)依赖项 "everywhere"?

java - 打破循环依赖以使用依赖注入(inject)

android - Retrofit 2 - 使用相同请求的内容管理 http "204 No content"和 "200"

java - 使用 Facebook .jar 从 Eclipse 导入错误?

java - 如何从字节数组计算音频剪辑的持续时间?

java - 模拟其属性在测试类构造函数中使用的依赖项

java - Eclipse Juno 中外部配置文件的 Checkstyle

java - 我如何学习如何使用 slf4j?

android - Dagger 2 和 Android 中的组件依赖