Лучший способ передать ссылку на класс внедренному экземпляру - PullRequest
0 голосов
/ 06 января 2012

Я пытаюсь получить работающий пример шаблона MVP (Passive-View) в приложении JSF2 с использованием CDI и аннотаций.

Моя цель состоит в том, чтобы отделить все соответствующие проекты. Это означает, что представление находится в jsf-war-project, а докладчик - в отдельной банке. Я немного слежу за примером Адама Бинса в Oracle, но я не хочу, чтобы докладчик знал что-либо о каркасе представления (в данном случае JSF).

Моя проблема в том, что презентатор должен быть внедрен в представление, но презентатор должен иметь конструктор параметров, который передается в текущем экземпляре представления. Поэтому я надеялся, что @ Inject-Annotation позволит что-то вроде @Inject (this), но это не так: - (

Я обошел эту проблему с помощью метода init с @PostConstruct, который вызывает установщик на презентаторе и передает его текущему представлению. Я думаю, что это самое близкое, что я могу получить в соответствии со спецификацией CDI ... не стесняйтесь поправлять меня, если я ошибаюсь.

View-аннотаций:

@Stereotype
@Named
@RequestScoped
@Target(TYPE)
@Retention(RUNTIME)
@Documented
public @interface View {}

Presenter-аннотаций:

@Stereotype
@Named
@Target(TYPE)
@Retention(RUNTIME)
@Documented
public @interface Presenter {}

Ведущий-экземпляр:

@Presenter
public class BikeGaragePresenter {

    BikeGarageView view;

    protected BikeGaragePresenter(){}

    public BikeGaragePresenter(BikeGarageView view){
        assert view != null;
        this.view = view;
    }


    public void save(){
        System.out.println(view.getOwner());
    }

    public void setView(BikeGarageView view) {
        this.view = view;
    }   
}

Просмотр экземпляра:

@View
public class BikeGarageBB implements BikeGarageView {

    @Inject
    private BikeGaragePresenter presenter;

    @PostConstruct
    public void init(){
        this.presenter.setView(this);
    }

    private String owner;

    public void setOwner(String owner) {
        this.owner = owner;
    }

    @Override
    public String getOwner() {
        return this.owner;
    }

    @Override
    public void displayMessage(String message) {


    }

    public void save(){
        presenter.save();
    }
}

Теперь вот мой вопрос: могу ли я каким-то образом извлечь этот шаблонный код (init-метод) в аннотацию (как-то похожую на Аспекты)? Я не знаю много о том, как писать аннотации ... Я обычно просто используйте их: -D

РЕДАКТИРОВАТЬ: точнее: можно ли использовать аннотации в качестве декоратора?

1 Ответ

2 голосов
/ 13 января 2012

Самый простой способ добиться того, чего вы хотите, - это лениво внедрить (чтобы избежать циклического внедрения) представление в презентере. Это будет выглядеть так:

Ведущий-экземпляр:

@Presenter
public class BikeGaragePresenter {

    BikeGarageView view;

    @Inject
    @Any
    Instance<BikeGarageView> viewInstances;

    public BikeGarageView getView()
    {
        return viewInstances.get();
    }       

    public void save(){
        System.out.println(view.getOwner());
    }


}

Просмотр экземпляра:

@View
public class BikeGarageBB implements BikeGarageView {

    @Inject
    private BikeGaragePresenter presenter;

    private String owner;

    public void setOwner(String owner) {
        this.owner = owner;
    }

    @Override
    public String getOwner() {
        return this.owner;
    }

    @Override
    public void displayMessage(String message) {


    }

    public void save(){
        presenter.save();
    }
} 
...