Shaharg
Shaharg

Reputation: 1029

Getting an injected object using CDI Produces

I have a class (OmeletteMaker) that contains an injected field (Vegetable). I would like to write a producer that instantiates an injected object of this class. If I use 'new', the result will not use injection. If I try to use a WeldContainer, I get an exception, since OmeletteMaker is @Alternative. Is there a third way to achieve this?

Here is my code:

@Alternative
public class OmeletteMaker implements EggMaker {
    @Inject
    Vegetable vegetable;

    @Override
    public String toString() {
        return "Omelette: " + vegetable;
    }
}

a vegetable for injection:

public class Tomato implements Vegetable {
    @Override
    public String toString() {
        return "Tomato";
    }

}

main file

public class CafeteriaMainApp {
    public static WeldContainer container = new Weld().initialize();
    public static void main(String[] args) {

        Restaurant restaurant = (Restaurant) container.instance().select(Restaurant.class).get();
        System.out.println(restaurant);

    }

    @Produces
    public EggMaker eggMakerGenerator() {
         return new OmeletteMaker();
    }


}

The result I get is "Restaurant: Omelette: null", While I'd like to get "Restaurant: Omelette: Tomato"

Upvotes: 0

Views: 425

Answers (1)

Lini
Lini

Reputation: 363

If you provide OmeletteMaker yourself, its fields will not be injected by the CDI container. To use @Alternative, don't forget specifying it in the beans.xml and let the container instantiate the EggMaker instance:

<alternatives>
    <class>your.package.path.OmeletteMaker</class>
</alternatives>

If you only want to implement this with Producer method then my answer may be inappropriate. I don't think it is possible (with standard CDI). The docs says: Producer methods provide a way to inject objects that are not beans, objects whose values may vary at runtime, and objects that require custom initialization.

Thanks Kukeltje for pointing to the other CDI question in comment: With CDI extensions like Deltaspike, it is possible to inject the fields into an object created with new, simply with BeanProvider#injectFileds. I tested this myself:

    @Produces
    public EggMaker eggMakerProducer() {
        EggMaker eggMaker =  new OmeletteMaker();
        BeanProvider.injectFields(eggMaker);
        return eggMaker;
    }

Upvotes: 1

Related Questions