infojolt
infojolt

Reputation: 5408

Pass constructor parameter into factory in Google Guice

I am trying to pass a constructor parameter from one class into the factory for another class:

public class PerPixelImageUpdater implements ImageUpdater {
    private final PixelUpdater pixelUpdater;
    private final BufferedImage image;

    @Inject
    PerPixelImageUpdater(PixelUpdaterFactory pixelUpdaterFactory,
                         @Assisted BufferedImage image){
        this.image = image;
        this.pixelUpdater = pixelUpdaterFactory.create(image);
    }

    //Methods
}

Factory:

public interface ImageUpdaterFactory {
    ImageUpdater create(BufferedImage image);
}

Register in Guice:

install(new FactoryModuleBuilder()
                .implement(ImageUpdater.class, PerPixelImageUpdater.class)
                .build(ImageUpdaterFactory.class));

When I run this code I get an error that the implementation was not bound?

1) No implementation for java.awt.image.BufferedImage annotated with @com.google.inject.assistedinject.Assisted(value="") was bound.
while locating java.awt.image.BufferedImage annotated with @com.google.inject.assistedinject.Assisted(value="") for the 2nd parameter of com.infojolt.imageencrypt.PerPixelImageUpdater.(PerPixelImageUpdater.java:16)

What have I missed? Do I need to register the factory in a different way?


Extra details:

There are actually two errors

1) No implementation for java.awt.image.BufferedImage annotated with @com.google.inject.assistedinject.Assisted(value="") was bound.
while locating java.awt.image.BufferedImage annotated with @com.google.inject.assistedinject.Assisted(value="") for the 2nd parameter of com.infojolt.imageencrypt.PerPixelImageUpdater.(PerPixelImageUpdater.java:16) at com.infojolt.imageencrypt.Injection.ImageEncryptModule.configure(ImageEncryptModule.java:25)

2) No implementation for java.awt.image.BufferedImage annotated with @com.google.inject.assistedinject.Assisted(value="") was bound.
while locating java.awt.image.BufferedImage annotated with @com.google.inject.assistedinject.Assisted(value="") for the 3rd parameter of com.infojolt.imageencrypt.SimplePixelUpdater.(SimplePixelUpdater.java:17) at com.infojolt.imageencrypt.Injection.ImageEncryptModule.configure(ImageEncryptModule.java:18)

In PixelShiftImageEncrypter, ImageUpdaterFactory imageUpdaterFactory is passed in to the constructor:

@Inject
PixelShiftImageEncrypter(PixelShiftCalculator pixelShiftCalculator,
                                ImageLoader imageLoader,
                                StringEncryption stringEncryption,
                                PixelModificationCalculator pixelModificationCalculator,
                                PixelSkipCountCalculator pixelSkipCountCalculator,
                                ImageUpdaterFactory imageUpdaterFactory)

(I am currently refactoring this project to reduce the number of constructor args / method params, but I'm trying to get the classed under test before ripping it apart.)

ImageUpdater is then created in a method by calling:

ImageUpdater imageUpdater = imageUpdaterFactory.create(image);

PixelShiftImageEncrypter is created in:

@Inject
EncryptJobConfiguration(@Assisted("inputString") String inputString,
                        @Assisted("secretKey") String secretKey,
                        @Assisted("inputImagePath") String inputImagePath,
                        ImageEncrypter imageEncrypter,
                        ImageStorage imageStorage)

ImageEncryptModule.java contains:

install(new FactoryModuleBuilder()
            .implement(JobConfiguration.class, Names.named("encrypt"), EncryptJobConfiguration.class)
            .implement(JobConfiguration.class, Names.named("decrypt"), DecryptJobConfiguration.class)
            .build(JobConfigurationFactory.class));

    install(new FactoryModuleBuilder()
            .implement(PixelUpdater.class, SimplePixelUpdater.class)
            .build(PixelUpdaterFactory.class));

    install(new FactoryModuleBuilder()
            .implement(ImageUpdater.class, PerPixelImageUpdater.class)
            .build(ImageUpdaterFactory.class));

PixelUpdaterFactory:

public interface PixelUpdaterFactory {
    PixelUpdater create(BufferedImage image);
}

JobConfigurationFactory:

public interface JobConfigurationFactory {
    @Named("encrypt")
    JobConfiguration createEncrypt(@Assisted("inputString") String inputString,
                                   @Assisted("secretKey") String secretKey,
                                   @Assisted("inputImagePath") String inputImagePath);

    @Named("decrypt")
    JobConfiguration createDecrypt(@Assisted("secretKey") String secretKey,
                                   @Assisted("inputImagePath") String inputImagePath);
}

This file also contains all of the other bindings which I've exclude for brevity. For example:

bind(ImageEncrypter.class).to(PixelShiftImageEncrypter.class);

Upvotes: 0

Views: 465

Answers (1)

infojolt
infojolt

Reputation: 5408

The problem was that I thought I had replaced:

bind(ImageUpdater.class).to(PerPixelImageUpdater.class);

with:

install(new FactoryModuleBuilder()
                .implement(ImageUpdater.class, PerPixelImageUpdater.class)
                .build(ImageUpdaterFactory.class));

However, the original binding hadn't been removed. Deleting these two line solved the problem:

bind(ImageUpdater.class).to(PerPixelImageUpdater.class);
bind(PixelUpdater.class).to(SimplePixelUpdater.class);

Upvotes: 2

Related Questions