문제

나는이 질문이 일부 또는 다른 방식으로 묻는다고 생각하지만 아직 얻지 못했습니다.

우리는 GWT 프로젝트를 수행하고 내 프로젝트 리더는 Gin/Guice를 DI 프레임 워크로 사용하지 않았으므로 (새로운 프로그래머는 그것을 이해하지 못할 것이라고 주장했다) 나는 수동으로 DI를하려고 노력했다.

이제 깊은 물체 그래프에 문제가 있습니다. UI의 객체 계층은 다음과 같습니다.

AppResenter-> DashboardPresenter-> GadgetPresenter-> GadgetConfigPresenter

객체 계층 트리 아래의 gadgetConfigPresenter는 CustomerRerepository, ProjectRepository, MidatorRepository 등과 같은 몇 가지 종속성을 가지고 있습니다.

따라서 GadgetConfigPresenter를 생성하는 GadgetPresenter는 이러한 종속성을 가지고 있으며 앱 프리 센터를 생성하는 앱의 진입 점까지.

  • 이것이 매뉴얼 DI가 작동하는 방식입니까?
  • 이것이 부팅 시간에 모든 종속성을 생성한다는 의미는 아니지만 필요하지 않습니까?
  • Gin/Guice와 같은 DI 프레임 워크가 여기서 나를 도울까요?
도움이 되었습니까?

해결책

당신은 그것을 씁니다

GadgetConfigPresenter를 만드는 가제트 프레 센터 [.

직접 제작하는 대신 GadgetConfigPresenter 인스턴스, GadgetPresenter ~해야 한다 추상 공장에 의존하십시오 그것은 만들 수 있습니다 GadgetConfigPresenter 그것에 대한 인스턴스. 이것은 내부 의존성을 밀어냅니다 GadgetConfigPresenter 공장에.

사용 생성자 주입 끝까지, 당신 가난한 사람의 di 배선은 이와 같은 것으로 보일 것입니다 (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 컨테이너를 추천합니다.

다른 팁

컨텍스트 인터페이스를 사용하여 DI를 수행 할 수 있습니다. 어렵지 않고 상당히 간단합니다.

컨텍스트 인터페이스는 GUICE 모듈 구성에서 모든 바인딩을 노출시키는 클래스입니다.

이것은 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