سؤال

نحن نقوم بتقييم استخدام GIN في مشروع GWT وحققنا نتائج جيدة من خلال الحقن النموذجي عبر وسيطات المُنشئ.الشيء الذي واجهنا صعوبة فيه هو الحقن على مستوى الميدان.تنتهي الحقول دائمًا إلى أن تكون فارغة.هل لدى أي شخص مثال جيد لكيفية تحقيق حقن المستوى المودع بشكل صحيح باستخدام GIN؟

تحديث:

فيما يلي بعض الأمثلة على التعليمات البرمجية المشابهة لرمزنا:

public class MVP implements EntryPoint {

  public static final HandlerManager EVENT_BUS = new HandlerManager(null);
  private final MVPInjector _injector = GWT.create(MVPInjector.class);

  public void onModuleLoad() {
    // set up layout for module
    RootLayoutPanel.get().add(mainPanel);

    // initialize presenters
    ListPresenter listPresenter = _injector.listPresenter();
    DetailPresenter detailPresenter = _injector.detailPresenter();

    listPresenter.go(listContainer);
    detailPresenter.go(detailContainer);

    // simulate data coming in from RPC call
    EVENT_BUS.fireEvent(new DataReadyEvent(getData()));
  }
}

public class ListPresenter {

  private final HandlerManager _eventBus;
  private final Map<String, Fruit> _myRecords = new HashMap<String, Fruit>();
  private final Display _view;

  @Inject
  public ListPresenter(Display argView, HandlerManager argEventBus) {
    _eventBus = argEventBus;
    _view = argView;
  }

  public void go(HasWidgets argContainer) {
    argContainer.clear();
    argContainer.add(_view.asWidget());
  }

  public interface Display {
    public Widget asWidget();

    public void clear();

    public SingleSelectionModel<ViewProxy> getSelectionModel();

    public void setData(List<ViewProxy> argData);
  }
}

public class DetailPresenter {

  private final HandlerManager _eventBus;
  private final Display _view;
  private Fruit _myRecord;

  @Inject
  private ImagePresenterFactory _imagePresenterFactory;

  @Inject
  private TestPresenter _testPresenter;

  @Inject
  public DetailPresenter(Display argView, HandlerManager argEventBus) {
    _view = argView;
    _eventBus = argEventBus;
  }

  public void go(HasWidgets argContainer) {
    argContainer.clear();
    argContainer.add(_view.asWidget());

    if (_testPresenter != null) {
      _testPresenter.go();
    }
  }

  public interface Display {
    public Widget asWidget();

    public HasText getDescriptionControl();

    public HasClickHandlers getImageControl();

    public HasText getNameControl();

    public HasClickHandlers getSaveControl();

    public void setEnabledControls(boolean argEnabled);
  }
}

public class TestPresenter {

  @Inject
  HandlerManager _eventBus;

  public TestPresenter() {}

  public void go() {
    if (_eventBus != null) {
      _eventBus.toString();
    }
    else {
      // event bus was not injected
    }
  }
}

@GinModules(MVPModule.class)
public interface MVPInjector extends Ginjector {

  DetailPresenter detailPresenter();

  ListPresenter listPresenter();

}

public class MVPModule extends AbstractGinModule {

  @Provides
  @Singleton
  public HandlerManager getEventBus() {
    return MVP.EVENT_BUS;
  }

  @Provides
  public TestPresenter getTestPresenter() {
    return new TestPresenter();
  }

  @Override
  protected void configure() {
    bind(ListPresenter.Display.class).to(ListView.class);
    bind(DetailPresenter.Display.class).to(DetailView.class);
    bind(ImagePresenter.Display.class).to(ImagePopup.class);
    install(new GinFactoryModuleBuilder().build(ImagePresenterFactory.class));
  }

  public interface ImagePresenterFactory {
    public ImagePresenter createImagePresenter(ImageResource argImage);
  }

}

في الكود أعلاه، قمت بإزالة معظم الكود الذي لا يتضمن GIN.تم إدخال TestPresenter الذي يتطلبه DetailPresenter بنجاح ولكن HandlerManager الذي يتطلبه TestPresenter يكون دائمًا فارغًا.كما ترون، لا يتم استخدام HandlerManager المحقون في المُنشئ.

هل كانت مفيدة؟

المحلول

التحديث، بالنظر إلى نموذج التعليمات البرمجية:

@Provides
public TestPresenter getTestPresenter() {
  return new TestPresenter();
}

نظرًا لأنك تقوم بإنشائه بنفسك، فهذا يفترض أنك تعاملت مع أي حقن.قم بإزالة هذه الطريقة، وسوف تقوم باستدعاء المنشئ الافتراضي (الحقن هناك إذا لزم الأمر)، ثم قم بزيارة أي موقع حقن آخر.

مشكلة أخرى يمكن أن تواجهها:هناك العديد من تلميحات HandlerManager، تأكد من أن جميع مراجعك إلى HandlerManager تستخدم نفس الحزمة.


الإجابة الأصلية:

ستكون فارغة عند تشغيل المنشئ، لكن هذا منطقي - كيف يمكن أن تكون لها أي قيمة أخرى، عندما لا يكون لدى الحاقن فرصة لتعيين جميع الحقول بعد.فكر في كيفية تشغيل هذا (يتم التعبير عنه هنا على أنه جافا قانوني مشكوك فيه، حيث قد لا تكون الحقول عامة):

InstanceToInject instance = new InstanceToInject(...);
instance.field = provideFieldValue();

بحلول الوقت الذي يصبح فيه الحقل مؤهلاً للتخصيص، يكون مُنشئك قد تم تشغيله بالفعل.

إذا كان الحقل فارغًا عند تشغيل أسلوب آخر، فتأكد من عدم تشغيل هذا الأسلوب من قبل المنشئ, ولكن يتم ذلك بعد انتهاء الحقن من عمله.الحالات الأخرى التي قد تكون فيها فارغة ستكون كذلك @Inject المستوطنون المشروحون.

بافتراض عدم وجود أي من هذه الحالات (أسهل طريقة للتحقق هي تعيين نقطة توقف، والتأكد من عدم وجود الحاقن في مكدس الاستدعاءات)، تأكد من أن الحقل يحتوي على @Inject, ، وأنه غير مرتبط بمثيل فارغ.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top