Внедрение зависимостей калитки

У меня есть страница с формой в Wicket, где форма требует соавтора для выполнения своей работы. Соавтор вводится (для чего я использую Guice) и выглядит примерно так:

public class RegistrationPage extends WebPage {
    @Inject
    public RegistrationPage(RegistrationService service) {
        this.service = service;
        add(new RegistrationForm());            
    }

    private class RegistrationForm extends Form {
        public RegistrationForm() {
            // setup
        }

        protected void onSubmit() {
           service.doSomething();
        }
    }
}

Мне не нравится идея, что RegistrationService внедряется в RegistrationPage, когда в этом нуждается только RegistrationForm. Я мог бы изменить RegistrationForm для получения RegistrationService:

public RegistrationForm(RegistrationService service) {
    this.service = service;
}

и удалите поле из RegistrationPage, но RegistrationPage по-прежнему используется для сквозной передачи.

Я предполагаю, что я спрашиваю, как лучше всего это делать? Можно ли это сделать, или, возможно, было бы лучше ввести саму форму регистрации на страницу:

   public class RegistrationPage extends WebPage {
        @Inject
        public RegistrationPage(RegistrationForm form) {
            add(form);
        }
   }

   ---

   private class RegistrationForm extends Form {
        private RegistrationService service;

        @Inject
        public RegistrationForm(RegistrationService service) {
            this.service = service;
        }

        protected void onSubmit() {
           service.doSomething();
        }
    }

Я бы предпочел это, так как хотел бы, чтобы регистрационная форма находилась в отдельном классе/файле. Я новичок в Wicket, поэтому не знаю, что такое норма - может ли кто-нибудь показать мне путеводную звезду? :)


person tddmonkey    schedule 18.02.2009    source источник


Ответы (2)


основная парадигма с wicket+ioc такова: большинство зависимостей следует внедрять через инъекцию сеттера. внедрение конструктора невозможно для веб-страниц.

компоненты/панели/формы/страницы должны быть только на принимающей стороне.

поэтому добавьте зависимость от RegistrationService к RegistrationForm , затем создайте ее на RegistrationPage с помощью add(new RegistrationForm());

у калитки есть IComponentInstantiationListener — один из них — guice. они получают уведомление во время конструктора каждого компонента/веб-страницы. поэтому ваша RegistrationForm будет иметь свои зависимости, введенные до того, как любая часть вашего кода сможет выполниться.

как бы я это сделал: (конечно, RegistrationForm может быть в другом файле)

public class RegistrationPage extends WebPage {

@Inject
public RegistrationPage() {
    add(new RegistrationForm());            
}

---
private static class RegistrationForm extends Form {
   RegistrationService service;

      @Inject
     public void setRegistrationService (RegistrationService  service){
     this.service = service;
        }
    public RegistrationForm() {
        // setup
    }

    protected void onSubmit() {
       service.doSomething();
    }
}
}

если вы решите поместить RegistrationForm внутрь страницы как внутренний класс, не забудьте объявить его статическим! вам, скорее всего, не понадобятся никакие ссылки на окружающий класс.

person Andreas Petersson    schedule 19.03.2009
comment
Молодец, Андреас, это как раз то, что мне нужно. Я не знал о IComponentInstantiationListener. - person tddmonkey; 20.03.2009

На мой взгляд, DI на Wicket имеет один запутанный элемент, он выполняется автоматически на компонентах или страницах, но не в моделях. На мой взгляд, именно модель (но не страница) должна иметь зависимость от JPA и т.д.

Официальный документ говорит использовать InjectorHolder.getInjector().inject(this)

person Jacek Cz    schedule 03.09.2015