2012-02-07 8 views
8

과거에는 ActionScript 3.0 IoC 컨트롤러 인 swiftsuspenders를 사용했습니다. 기본적으로 switfsuspender의 첫 번째 버전은 인젝터 (injector)라고 불리는 Ninject 커널과 비슷한 것을 가지고있었습니다.더 많은 실제 사례가 필요합니다.

응용 프로그램 인젝터를 만들고 싶다면 (응용 프로그램 전체에서 가장 관련있는 매핑을 사용한다고 가정 해 봅시다) 인젝터 자체를 응용 프로그램 클래스에 주입해야했습니다.

응용 프로그램의 여러 클래스 중에서 kernel.get <>을 사용하는 것이 무엇인지 궁금합니다. 커널 자체를 주입해야합니까?

필자는 개인적으로 kernel.inject를 사용하고 싶지만 kernel.inject를 할 수 있다면 필자는 수동으로 종속성을 주입 할 가능성이 높습니다 (키스).

테스트 사례는 훌륭하지만 실제로 실제적인 문제와는 거리가 멀기 때문에이 점을 명확하게 설명 할 수 있기를 바랍니다. 고맙습니다.

편집 : 일부 사람들이 "루트 컨테이너"에 대해 말한 것으로 나타났습니다. 내가 찾고있는 개념 인 것 같습니다. 루트 컨테이너를 설정하고 다른 응용 프로그램 클래스에서이를 어떻게 알 수 있습니까?

Edit2가 샘플 코드 (그냥 예 위해서입니다, 오류를 용서하십시오) : 난 아직도 일부 초기화 문제로 싸우고 있기 때문에

class SomeClass 
{ 
    public SomeClass() 
    { 
     Command cmd = new Command(); 

     cmd.execute(); 
    } 

} 

class SomeOtherClass:ISomeOtherClass 
{ 
public void allright() 
{ 
    //right 
} 
} 

class Command 
{ 
    ISomeOtherClass dependency; 

    void execute() 
    { 
    dependency.allright(); 
    } 

} 


Program.Main() 
{ 
    IKernel kernel = new StandardKernel(); 

    kernel.Bind<SomeClass>().ToSelf().InSingletonScope(); 
    kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>(); 

    SomeClass sc = kernel.Get<SomeClass>(); 
} 

나는, 아직 테스트하지 못했지만, 내 질문은, 어떻게 명령 클래스는 SomeOtherClass에 대해 알고 있습니까? 나의 현재의 가설은 SomeClass에 커널을 삽입하고 Inject 메소드를 사용하는 것이다.

답변

11

예제를 보면 SomeClass은 Inversion of Control을 염두에 두지 않은 것이 분명합니다. 그 팁 오프는 Command에 대한 의존성을 가지지 만 그 종속성의 제어는 SomeClass 내부에서 유지됩니다. (Command cmd = new Command();)

에 해당 종속성의 컨트롤을 반전하려면 해당 종속성을 SomeClass에 주입 할 방법이 필요합니다. Remo Gloor has indicated처럼 Ninject로 표준 작업을 수행하는 방법은 생성자를 사용하는 것입니다.

이렇게하려면, 당신은 이런 식으로 SomeClass을 변경할 수 있습니다

class Command 
{ 
    private ISomeOtherClass _dependency; 

    public Command(ISomeOtherClass injectedSomeOtherClass) 
    { 
     _dependency = injectedSomeOtherClass; 
    { 

    void execute() 
    { 
     _dependency.allright(); 
    } 
} 

그런 다음 당신은 당신의 명령에 바인딩을 등록 할 것입니다 :

class SomeClass 
{ 
    private ICommand _command; 

    public SomeClass(ICommand injectedCommand) 
    { 
     _command = injectedCommand; 
     _command.execute(); 
    } 

} 

은 마찬가지로 당신은 의존성을 광고하도록 명령해야 커널은 아마도 다음과 같습니다 :

Program.Main() 
{ 
    IKernel kernel = new StandardKernel(); 

    kernel.Bind<SomeClass>().ToSelf().InSingletonScope(); 
    kernel.Bind<ICommand>().To<Command>(); 
    kernel.Bind<ISomeOtherClass>().To<SomeOtherClass>(); 

    SomeClass sc = kernel.Get<SomeClass>(); 
} 

커널은 다음을 수행 할 수 있습니다. 그는 의존성 사슬과 그들을 모두 주입.

+0

해답을 주셔서 감사 합니다만, 그것이 옳은 동안, 모든 종속성을 사전에 알아야한다고 말합니다. 이것이 불가능할 때 어떻게됩니까? (물론 내가 말하는 것은 객체가 동적으로 생성 될 때만 의미가 있습니다.) – sebas

+0

SomeClass가 최종 수의 동적 객체를 만들어야한다고 가정 해 봅시다. SomeClass가 Level이되어 30 개의 별을 만들어야합니다. 별들은 어떤 의존성을 가지고 있습니다. 어떻게 레벨이 커널을 사용하여 별들에 의존성을 주입시킬 수 있습니까? – sebas

+0

좋은 질문입니다.이 형식으로 대답 할 수있는 간단한 의존성 주입 질문을 넘어서고 있습니다. 이런 종류의 상황 (복잡한 객체 생성)은 한 조각 더 필요로하는 경향이 있는데, 이는 Remo가 공장에서 그의 대답을 언급 한 이유입니다. 별 - 빌딩 팩토리를 생성하고이를 SomeClass에 삽입하거나 Ninject가 팩터 리 메소드 자체 또는 Bind()를 사용하여 별을 해석하도록해야합니다. ToProvider(). –

5

가능하면 생성자 삽입을 사용하고 인스턴스에 종속 된 개체와 함께 인스턴스를 만들지 않을 충분한 이유가있을 때마다 Factories을 사용하십시오.

kernel.Inject은 개체 생성이 변경되지 않은 경우에만 사용해야합니다. 예 : 웹폼

kernel.Get은 구성 루트 (예 : Program.Main 또는 MVC3.DependencyResolver)에서 정확히 한 번 사용하여 응용 프로그램을 만들어야합니다.

+2

안녕하세요! 답변 감사합니다. 당신은 유용한 정보를 제공해 왔지만, 내가 알고 싶은 정보가 아닙니다. 당신은 서비스 로케이터로 사용해서는 안된다고 말하고 있지만, 내가 물었던 것은 이것보다 더 많습니다. 그 중 한 가지 방법으로 명령을 생성해야하는 클래스가 있다고 가정 해 봅시다. 명령에 일부 종속성이 주입되어야하고 커널이 명령을 생성하는 클래스 외부에 정의되었다고 가정 해 봅시다. 이 커맨드의 의존성을 주입하기 위해 어떻게 커널을 사용해야합니까? 먼저 커맨드를 생성하는 클래스에 커널을 삽입해야합니까? – sebas

+0

내 문제는이 http://stackoverflow.com/questions/2862698/ninject-shared-di-ioc-container와 비슷하지만 정적 클래스를 사용하지 않기 때문에이 시점에서 커널을 주입하는 것이 좋습니다. – sebas

+0

당신이하고 싶은 것에 대한 질문에 코드 예제를 추가해야합니다. 다른 모든 것은 단지 추측 일뿐입니다. 일반적으로 Ninject에 의해 자동으로 수행되는 생성자 삽입을 사용하여 종속성을 전달해야합니다. –

관련 문제