2016-09-21 2 views
0

기계 자동화 소프트웨어에 Ninject 종속성 주입을 사용하고 있으며 순환 참조에 문제가 있습니다. 우리는 충돌을 피하기 위해 서로를 알아야 할 몇 가지 물리적 인 물체를 가지고 있습니다. 우리는 각 동작을 인증하는 CollisionHandler 클래스를 추가했습니다. 예 : 로봇 암은 해치가 이동하기 전에 열려 있는지 확인합니다. 그리고 해치는 닫히기 전에 로봇 팔이 방해가되지 않았는지 확인합니다.지연된 Ninject 설정 메소드 삽입

로봇과 충돌 처리기만으로 Ninject setter method injection pattern의 개념 증명 테스트를 수행했습니다. 그게 잘 작동, 먼저 로봇이 만들어진 다음 CollisionHandler 그리고 마지막으로 주사 메서드가 로봇에 호출되었습니다. 두 로봇, 해치 및 CollisionHandler가 싱글로 바인딩 :

Bind<Robot>().ToSelf().InSingletonScope() 
Bind<Hatch>().ToSelf().InSingletonScope() 
Bind<CollisionHandler>().ToSelf().InSingletonScope() 

public class Robot 
{ 
    private CollisionHandler _collisionHandler; 

    public Robot(ISomeService someService) 
    { 
    } 

    [Inject] 
    public void PostConstructInject(CollisionHandler collisionHandler) 
    { 
     if (_collisionHandler != null) 
      throw new InvalidOperationException("PostConstructInject called more than once"); 
     _collisionHandler = collisionHandler; 
    } 
} 

public class CollisionHandler 
{ 
    private readonly Robot _robot; 
    private readonly Hatch _hatch; 

    public CollisionHandler(Robot robot, Hatch hatch) 
    { 
     _robot = robot; 
     _hatch = hatch; 
    } 

    public bool IsRobotAwayFromHatch() { } 
    public bool IsHatchOpen() { } 
} 

그것은 모두가 잘 보였다는 그래서 다른 엔티티에 대한 패턴을 구현에 옮겼습니다. 그것이 작동을 멈췄습니다.

Activation path: 
4) Injection of dependency CollisionHandler into parameter collisionHandler of method PostConstructInjection of type Robot 
3) Injection of dependency Robot into parameter robot of constructor of type CollisionHandler 
2) Injection of dependency CollisionHandler into parameter collisionHandler of method PostConstructInjection of type Hatch 
1) Request for Hatch 

:

public class Hatch 
{ 
    private CollisionHandler _collisionHandler; 

    public Hatch(ISomeOtherService someOtherService) 
    { 
    } 

    [Inject] 
    public void PostConstructInject(CollisionHandler collisionHandler) 
    { 
     if (_collisionHandler != null) 
      throw new InvalidOperationException("PostConstructInject called more than once"); 
     _collisionHandler = collisionHandler; 
    } 
} 

문제는 Ninject에 개체를 건설 한 후 직접 분사 메소드를 호출하고 싶어한다는 것입니다 : 해치에 분사 방법을 추가, Ninject에 더 이상 객체 그래프를 생성 할 수 없습니다 내가 할 싶은 무엇

Robot robot = new Robot(someService); 
robot.PostConstructInject(/* We need a CollisionHandler instance before it is constructed */); 
Hatch hatch = new Hatch(someOtherService); 
CollisionHandler collisionHandler = new CollisionHandler(robot, hatch); 
hatch.PostConstructInject(collisionHandler); 

PostConstructInject가 CollisionHandler 인스턴스가 CRE 된 후 호출 이동하는 것입니다 : 이것은 다음 코드를 동일 ated :

Robot robot = new Robot(someService); 
Hatch hatch = new Hatch(someOtherService); 
CollisionHandler collisionHandler = new CollisionHandler(robot, hatch); 
robot.PostConstructInject(collisionHandler); 
hatch.PostConstructInject(collisionHandler); 

Ninject에게 주입 방법을 호출 할 때까지 기다릴 수있는 방법이 있습니까? 나는 [Inject] 속성을 제거하고 CollisionHandler가 그 메소드를 호출하도록 할 수는 있지만 꽤 추함을 느낍니다.

+0

개별 구성 요소가 시스템을 구동하는 대신 전체 프로세스를 조정하는 방식이 필요하다고 생각합니다. 해치와 팔은 서로에 대해 관심을 가져서는 안되며, 특정한 일을하고 있으며 이것을 처리하는 것은 오케스트레이터 (아마도 로봇 클래스)에게 달렸습니다. 이는 구성 요소를 간단하고 견고하게 유지하고 책임을 분리 할 수 ​​있기 때문에 유용합니다. –

답변

1

이렇게하는 방법이 있습니다. 그러나 일반적으로 이와 같은 주기적 종속성이있는 경우 디자인에 잘못된 경로가 있습니다. 순환 종속성을 가질만한 이유가 거의 없습니다. 그것들은 인스턴스를 만드는 것뿐만 아니라 많은 것을 복잡하게 만듭니다. 유지 보수가 어려울 수있는 완전히 얽힌 디자인으로 쉽게 끝납니다.

내 경고에도 불구하고이 경로를 따르려면 Lazy에 대한 공장 확장 및 지원을 살펴보십시오. 나는 이것이 정말로 좋은 디자인이 아닌 것 같아서 당신에게 더 많은 힌트를주지 않을 것입니다.

관련 문제