CDI and custom components basic question

Hey guys, I’m new to vaadin and CDI but I am liking the combination a lot. I have a general question about crating custom components and the best practices to use them with CDI, hopefuly someone will understand it and be able to guide me :slight_smile:
I won’t be posting a lot of code example right now, as I don’t think it will be necessary since the question isn’t really complex. But if it eventually becomes necessary, i will create an example project.

Let’s start then. I created a custom component (lets call it CC) that extends VerticalLayout and has a proprietary Service injected into it, but I didn’t make CC’s scope explicit yet (like @NormalViewScoped). In this component, I declared an init method (not a @PostConstruct) which receives a pojo as parameter and populates its fields.

After this, i declared a CDIView that has a TabSheet. It starts with one tab, which will have a table on it, populated by the same type of pojo as before. I added a clicklistener to the table so that once someone clicks on one of the items it does the following:

  • Checks if a Tab with caption equals to the pojo’s name attribute already exists in the TabSheet.
    [list]
  • If it does, set such tab as selected.
  • If it doesn’t, then it creates a CC, calls its init method with the clicked pojo, and adds CC as a new tab with the pojo name as caption.

    [/list]

Before utilizing cdi, I would simply call new CC() and then init(pojo). However, now i am Injecting something into CC, therefore i can’t actually call new, otherwise the injection will not work. I thought of injecting CC into the CDIVIew, but it would only be one attribute which would have its fields overwritten, whereas what i actually need is always a new instance of CC to be added to the tabsheet.

Is there an elegant way to solve this with vaadin and cdi? The approach i had to take was the following:
I created a class that handles CC production, CCProducer. I injected the service into it and created a getCC method, that:

  1. Receives the pojo as param
  2. Creates a new CC (removed injection from it, went back to using new CC() )
  3. Initializes the CC with the POJO
  4. Sets the new CC service with the producer’s injected service
  5. Returns CC

Then i injected this new producer class to my cdi view, and where i would create the new tabs i replaced the calls for the producer’s getCC method.

The problem i see with this approach, is that if i ever want to add something to CC, like say a button that opens a custom window with injected stuff, I won’t be able to inject the window to it and etc, because CC went back to being a non JEE class…

Suggestions?

Hello Jorge,

You can inject an Instance of your CC, like this:

@Inject Instance<CC> myCC;

Then, when you need a new instance of the CC, do this:

addComponent(myCC.get());

Hope this helps!

-Petter-

Petter,

Only had time to test it now, but using Instance<> solved everything i needed and more. Thank you so much for the reply :slight_smile:

Jorge