8

구조체 맵에서 원형 의존성이 가장 단순합니다. 클래스 A는 생성자에서 클래스 B를 사용하고 클래스 B는 생성자에서 클래스 A를 사용합니다. 의존성을 없애기 위해 클래스 B를 클래스 A를 생성자 인수가 아닌 속성으로 가져 왔지만 구조체 맵은 여전히 ​​불평합니다.StructureMap의 순환 종속성 - 속성 주입으로 손상 될 수 있습니까?

다른 DI 프레임 워크에서이 방법을 사용하여 순환 종속성이 손상된 것을 보았습니다 .-이 문제는 Structuremap과 관련이 있습니까? 아니면 잘못된 것입니까?

편집 :

x.For<IB>().Singleton().Use<B>().Setter(y => y.ArrayOfA).IsTheDefault(); 

그냥 내가 발생하는 다음과 같은 일련의 이벤트를 원 명확히하기 : 내가 그 클래스 B의 속성이처럼 유선 클래스 A의 인스턴스의 배열입니다 언급해야한다 :

  • 생성자로 "B"를 주입, 작도의 "를"A의 인스턴스를 "B"
  • 를 B의 인스턴스를 생성
  • 세트 [ "A"]

에 "b.ArrayOfA"내가 원하는 모든이

편집 2 ... 가능하면에서 autowiring을 사용하여 발생합니다 : 여기 사용하는 간단한 예제 "양방향 종속성 문제가 RequestedType 검출 : IocTest2.ILoader ..."구성 원인을 검증

interface ILoader { } 
interface ILoaderManager { } 

class Loader : ILoader 
{ 
    public Loader(ILoaderManager lm) { } 
} 
class LoaderManager : ILoaderManager 
{ 
    public ILoader Loader { get; set; } // Was an array, but same circular dependency appears here 
} 

ObjectFactory.Configure 
(
    x => 
    { 
     x.For<ILoader>.Singleton().Use<Loader>(); 
     x.For<ILoaderManager>().Singleton().Use<LoaderManager>().OnCreation((c, a) => a.Loader = c.GetInstance<ILoader>()); 
    } 
); 

:까지 명시 배선

답변

3

당신이 얻을 수있는 가장 가까운이 같은 것입니다 :

x.For<IB>().Use<B>() 
    .OnCreation((ctx, instance) => 
    { 
     instance.ArrayOfA = new IA[] {new A(instance) }; 
    }); 

A에 컨테이너에서 확인하려는 다른 종속성이있는 경우 OnCreation 람다 내의 ctx에서 검색 할 수 있습니다.

+0

안녕하세요 Joshua - 방금줬고 "Bidirectional Dependency Problem"이 있습니다 - 이것이 StructureMap의 순환 종속성의 신호라고 생각하십니까? StructureMap에 의한 객체의 구성 및 설정이 효과적으로 원 자적 참조가 해결 될 수 없습니까? 가능성은 낮지 만 지금까지는 작동하지 못했습니다 ... – Andy

+0

양방향 종속성 문제는 순환 참조를 나타냅니다. 그러나 OnCreation 람다가 호출되기 전에 B의 인스턴스가 만들어지기 때문에 내가 제공 한 코드 샘플이 작동합니다. 그런 다음 B의 해당 인스턴스를 A의 생성자로 전달한 다음 B의 속성을 A로 설정할 수 있습니다. 위 코드를 테스트 한 결과 작동합니다. 순환 참조 문제가 계속 발생하면 언급하지 않은 다른 종속성이 있어야합니다. –

+0

코드 예제를 사용할 때 StructureMap에서 B에 대한 setter 주입을 수행하도록 정책을 설정하면 안된다는 것을 분명히해야합니다. OnCreation 람다에서 수동으로 setter 주입을 수행하고 있습니다. –

0

StructureMap은 가능성이 높은 Setter Injection을 처리 할 것입니다. 해결할 개체에 대해 공용으로 설정할 수있는 속성을 채 웁니다. 문서에 따르면, 기본적으로

는, 모든 공개 "세터는"그들은 명시 적으로 특정 인스턴스에 대한 구성되어있는 경우 이러한 세터에만 설정됩니다 즉, 선택 사항

그래서 우연히 당신이 자동 유선이되도록 속성을 설정 하시겠습니까? 그렇다면 순환 종속성 문제가 계속 발생합니다.

편집 : 나는 당신이 가지고있는 것을 본다. B가 A [] 주입 때문에 귀하의 경우에, StructureMap이 필요로하는 B 각 A의 의존성을 해결해야합니다 A [], 등등 ...

+0

IIRC, 나는 성 윈저에서 같은 일을 시도했다. 구성 요소의 생성자를 확인한 후 속성 확인을 수행 했으므로 순환 종속성이 효과적으로 손상되었습니다. 이 사실을 꿈꾸지 않는다고 가정하면, StructureMap이 비슷한 시설을 가지고 있는지 궁금합니다. – Andy

+0

여기에는 Windsor 및 StructureMap과 함께 순환 종속성 솔루션의 예가 나와 있습니다 (http://bit.ly/aZsr9c). 조금 나이가 들지만 여전히 적용될 수 있습니다. 마지막으로 SetterDependency 구성에 TheInstanceNamed ("Processor1")'을 사용했음을 알았습니다. 어쩌면 도움이 될까요? – statenjason

+0

안녕하세요. 도움과 링크를 많이 보내 주셔서 감사합니다. 나는 그것을 풀어주고 여전히 순환 의존성을 얻었다. 문제를 설명하기 위해 작은 코드 스 니펫으로 내 질문을 수정했습니다. – Andy

5

StructureMap은 지연 해상도를 사용하여 해결 방법을 사용하여 양방향 상황을 처리 할 수 ​​있습니다.당신이 ClassBClassA의 의존 ClassB에 따라 ClassA 같은 간단한 상황이있는 경우

, 당신은 그들 중 하나를 선택하고 게으른 종속성으로 종속성을 변환 할 수 있습니다. 이 방법은 나를 위해 일한 그 오류가

public class ClassA 
{ 
    private readonly Lazy<IClassB> _classB; 

    public Thing1(Lazy<IClassB> classB) 
    { 
     _classB = classB; 
    } 

    public IClassB ClassB => _classB.Value; 
} 

public class ClassB 
{ 
    public IClassA _classA { get; set; } 

    public ClassB (IClassA classA) 
    { 
     _classA = classA; 
    } 
} 

더 많은 정보를 원하시면 여기 .. ​​다시 등장하지 : http://structuremap.github.io/the-container/lazy-resolution/

+0

이것은 받아 들여진 답변보다 ** 많이 ** 우수합니다. –