كيفية القيام دليل DI مع الرسوم البيانية الكائن العميق والعديد من التبعيات بشكل صحيح

StackOverflow https://stackoverflow.com/questions/2425458

  •  19-09-2019
  •  | 
  •  

سؤال

أعتقد أن هذه الأسئلة قد سئلت في بعض أو الطريقة الأخرى ولكني لا أحصل عليها بعد.

نحن نقوم بمشروع GWT وقائد مشروعي غير مسموح باستخدام GIN / Guice كإطار عامل (مبرمجات جديدة لن يفهمها، جادل) لذلك أحاول أن أفعل DI يدويا.

الآن لدي مشكلة في الرسوم البيانية الكائن العميق. يشبه التسلسل الهرمي للكائن من واجهة المستخدم:

apppresenter-> dashboardpresenter-> gadgetpresenter-> gadgetconfigpresenter

The Gadgetconfigpresenter طريقة أسفل شجرة التسلسل الهرمي لها عدد قليل من التبعيات مثل العظام، وجهاز التوجيه، والفلتات، والآلات التوريزية، إلخ.

لذلك يحتوي GADGETPRESENTER الذي يقوم بإنشاء Gadgetconfigpresenter أيضا هذه التبعيات وهلم جرا، ما يصل إلى نقطة إدخال التطبيق التي تنشئ Apppresenter.

  • هل هذه الطريقة دليل DI من المفترض أن تعمل؟
  • لا يعني هذا أن أقوم بإنشاء جميع التبعيات في وقت التمهيد حتى لا أحتاج إليهم؟
  • هل سيساعدني إطار العمل مثل الجن / الغيار هنا؟
هل كانت مفيدة؟

المحلول

تكتب ذلك

gadgetpresenter الذي يخلق gadgetconfigpresenter [.

بدلا من إنشاء مباشرة GadgetConfigPresenter الحالات، GadgetPresenter ينبغي تأخذ التبعية على مصنع مجردة التي يمكن أن تخلق GadgetConfigPresenter مثيلات لذلك. هذا يدفع التبعيات الداخلية GadgetConfigPresenter إلى المصنع.

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

var customerRepository = new CustomerRepository(/*...*/);
var projectRepository = new ProjectRepository(/*...*/);
var mandatorRepository = new MandatorRepository(/*...*/);

var gadgetConfigPresenterFactory = 
    new GadgetConfigPresenterFactory(
        customerRepository,
        projectRepository,
        mandatorRepository);

var gadgetPresenter = new GadgetPresenter(gadgetConfigPresenterFactory);
var dashboardPresenter = new DashboardPresenter(gadgetPresenter);
var appPresenter = new AppPresenter(dashboardPresenter);

لاحظ كيف نحن كسر سلسلة التبعية في كثير من الأحيان، ضمان أن عدد التبعيات لكل مستهلك لا يصبح أبدا كبيرا جدا.

من حيث المبدأ، وهذا يعني أنه يجب عليك إنشاء جميع التبعيات في وقت التمهيد، ما لم تنفذ استراتيجية التحميل كسول.

مثل هذه الأشياء مثل إدارة العمر هي بالضبط نوع الشيء حيث يمكن أن تكون حاوية DI مفيدة بشكل كبير، ولكن من الممكن تماما كتابة تطبيق كامل من قبل بعد أنماط ومبادئ di.

الكل في الكل، ولكن، ما زلت أوصي بحاوية دي إذا كان ذلك ممكنا.

نصائح أخرى

يمكنك القيام DI باستخدام واجهات السياق. انها ليست صعبة، إلى الأمام على التوالي إلى حد ما.

واجهة السياق هي فئة تعرض كل الارتباطات من تكوين وحدة الغيار.

هذا مثال على ذلك حيث أفترض أن Apppresenter + DashboardPresEnter في حزمة واحدة وتحتاج إلى "سياق" واحد، في حين أن GadgetPresenter و Gadgetconfigpresenter في حزمة أخرى وتحتاج إلى "سياق" آخر. عدد السياقات، وكيفية التعامل معها هو ما يصل تماما إلى المستخدم.

/**
 * The dependencies that need to be injected for package1
 */
public interface SomePackageContext {
  GadgetPresenter getGadgetPresenter();
  GadgetConfigPresenter getGadgetConfigPresenter();
}

/**
 * The dependencies that need to be injected for package2
 */
public interface OtherPackageContext {
  // These methods can take arguments..
  AppPresenter getAppPresenter(Args..);
  DashboardPresenter getDashboardPresenter(Args..);
}

/**
 * All of the DI needed in our project.
 *
 * <p>We don't need the two interfaces above, we can put 
 * everything in this interface if we have a small
 * project where layering is not a big issue.
 */
public interface PresenterContext 
    extends SomePackageContext, OtherPackageContext {
}


public class MockPresenterContext implements PresenterContext {
  ...
}

public class RealPresenterContext implements PresenterContext {
  // This is similar to bind(...) in guice
  public AppPresenter getAppPresenter(Args..) {
    return new AppPresenter(this, otherargs...);
  }
  public DashboardPresenter getDashboardPresenter(Args..) {
    return new DashboardPresenter(this, otherargs...);
  }
  public GadgetPresenter getGadgetPresenter() {
    return new GadgetPresenter(this);
  }
  public GadgetConfigPresenter getGadgetConfigPresenter() {
    return new GadgetConfigPresenter();
  }
}

public class DashboardPresenter {

  // @Inject
  private final GadgetPresenter gadgetPresenter;

  /*
   * We inject everything using the SomePackageContext.
   */
  public DashboardPresenter(SomePackageContext ctxt) {
    this.gadgetPresenter = ctxt.getGadgetPresenter();
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top