2014-07-17 4 views
2

내가 Guice가 주입을 지원하는 것으로부터 : 생성자, Setter (어떤 이유에서든 메소드 주입이라고 부름), 필드.Guice는 방법 주입 (비 주입 주입)을 지원합니까?

메소드 매개 변수를 삽입 할 수 있습니까? 예를 들어 :

void foo(InterfaceA a, InterfaceA a1){ 
    ... 
} 


interface InterfaceA{ 
    ... 
} 


class A implements InterfaceA{ 
    .... 
} 

class B implements InterfaceA{ 
    .... 
} 

나는 (아마도 주석을 필요로하지만 초 동안 그 무시 할 것) B-Aa1를 입력 fooa을 결합 할 수 있어야합니다. 이 작업은 호출에서 수행하고 싶습니다.

이것은 개체 생성보다는 호출시 종속성 삽입이 발생한다는 점에서 일반적인 사용 사례 (c'tor, fields, setters)와는 다른 것으로 보입니다.

이렇게 가능합니까?

답변

3

글쎄, 당신은이 작업을 수행 할 수 있습니다

Injector injector = Guice.createInjector(b -> { 
    b.bind(InterfaceA.class).annotatedWith(Names.named("a")).to(A.class); 
    b.bind(InterfaceA.class).annotatedWith(Names.named("a1")).to(B.class); 
    b.bind(Invoke.class); 
}); 


public class Invoke { 
    private final Injector injector; 

    @Inject 
    Invoke(Injector injector) { 
     this.injector = injector; 
    } 

    public void invoke() { 
     this.foo(
      injector.getInstance(Key.get(InterfaceA.class, Names.named("a"))), 
      injector.getInstance(Key.get(InterfaceA.class, Names.named("a1"))) 
     ); 
    } 

    void foo(InterfaceA a, InterfaceA a1){ 
     ... 
    } 
} 

그러나 아무것도 더. Guice는 종속성 프레임 워크이며 대개 "구조 모든 종속성이있는 객체"를 의미합니다. 메서드 매개 변수 (클래스가이를 사용하기로되어 있기 때문에 의존성 정의 임) 형식적으로 의존성이 있지만 일반적으로 DI 프레임 워크의 것으로 간주되지 않습니다. 이해할 수 있습니다. 이렇게하면 이러한 프레임 워크가 거의 아무런 이득없이 복잡해질뿐만 아니라 Java는 외설적으로보기 흉하게 보이지 않는 언어를 표현하기에 충분하지 않습니다.

+0

+1을하지만 [추가 후속 않음 (http://stackoverflow.com/a/24811641/1426891) Injector 대신 Providers 사용. –

6

Vladimir's answer이 정확한 것은 아니지만 인젝터를 주입하는 대신 현장 주입 및 제공자를 사용하여 더 간결하게 동일한 작업을 수행하고 인젝터 작성 시간에 의존성이 충족되는지 확인할 수 있습니다. 이것은 코드가 자신과 동일하지만, 공급자 사용하도록 수정 :

Injector injector = Guice.createInjector(b -> { 
    b.bind(InterfaceA.class).annotatedWith(Names.named("a")).to(A.class); 
    b.bind(InterfaceA.class).annotatedWith(Names.named("a1")).to(B.class); 
    b.bind(Invoke.class); 
}); 

public class Invoke { 
    // Constructor injection works too, of course. These fields could also be 
    // made private, but this could make things difficult to test. 
    @Inject @Named("a") final Provider<InterfaceA> aProvider; 
    @Inject @Named("a1") final Provider<InterfaceA> a1Provider; 

    public void invoke() { 
     this.foo(aProvider.get(), a1Provider.get()); 
    } 

    void foo(InterfaceA a, InterfaceA a1){ 
     ... 
    } 
}